簡體   English   中英

React加快了嵌套組件的渲染速度

[英]React speed up rendering of nested components

我正在嘗試使用React來實現語法熒光筆。 語法highligher組件本身是Redux獨立的,但是Redux仍然是相關的。

熒光筆需要2個道具

structure -這是一個二維數組,其中包含要渲染的令牌ID,分為幾行,例如:

const structure = [
  [ // a line
    "ryMtafN9b",
    "r1WftTfEcZ",
    "rkfftaMV5W"
  ],
  [ // another line
    "B1sGYTG4cZ",
    "By3MYpzEq-"
  ],
  ...
]

tokens -令牌ID和令牌之間的映射,例如:

const tokens = {
  "ryMtafN9b": {
    "type": "LEFT_SQUARE_BRACKET",
    "value": "[",
    "id": "ryMtafN9b"
  },
  "r1WftTfEcZ": {
    "type": "WHITESPACE",
    "value": "  ",
    "id": "r1WftTfEcZ"
  },
  "rkfftaMV5W": {
    "type": "LEFT_CURLY_BRACKET",
    "value": "{",
    "id": "rkfftaMV5W"
  },
  ...
}

然后,渲染就這樣進行(刪除了所有不相關的內容):

一個令牌

class TokenElement extends PureComponent {
  render() {
    // return a <span> based on the token type, etc
  }
}

一行(行)

class TokenRow extends PureComponent {
  render() {
    const { tokens } = this.props
    return (<div>
      {tokens.map((token) => <TokenElement token={token} key={token.id} />)}
    </div>)
  }
}

實際的熒光筆組件

class JsonSyntaxHighlighter extends PureComponent {
  render() {
    const { tokens, structure } = this.props
    return (<pre>
      {
        structure.map((line) => (<TokenRow tokens={line.map((tokenId) => tokens[tokenId])} />))
      }
    </pre>)
  }
}

問題之所以我實現自定義語法熒光筆,是因為我需要基於異步傳入的數據在令牌級別添加自定義修飾。 這些更新以擴展tokens對象中的每個令牌的形式出現,而沒有通過reducer進行更改(整個熒光筆組件由連接的智能組件呈現)。 即使所有組件都是PureComponent ,單個令牌的重新渲染也需要很長時間,因為:

  1. JsonSyntaxHighlighter檢查是否需要更新- (因為tokens對象在道具中已更改)
  2. TokenRow檢查是否需要更新- (因為它的tokens數組已更改,因為它是map ping的結果)
  3. TokenElement檢查是否需要更新MAYBE (因為現在我可以正確地依賴shouldComponentUpdate )。

現在,當許多這樣的小更新以相對較小的間隔到達時,由於大量的重新提交排隊,因此UI只是阻塞了。

問題我可以更好地構造數據或組件的結構,以便頻繁地更改單個令牌的狀態而無需檢查整個樹就可以快速觸發渲染嗎?

Facebook在這個主題上有一篇很棒的文章。

簡短的答案是慷慨地使用React的shouldComponentUpdate生命周期方法來指定整個組件樹何時應避免更新。 以下是一些有關如何執行此操作的示例。

我沒有合適的代碼示例(在此處發布太多代碼),但最終解決此問題的方法是使用Observable s( rxjsbuffer運算符)將大量存儲更新分批處理。 由於狀態合並不是很自然的,這使化簡代碼變得更加復雜,但是現在我可以完全控制商店更新的發生頻率,這意味着可以控制render頻率。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM