React之childExpirationTime

前言:
在上篇文章React源碼解析之workLoop
中有提到 React 利用 childExpirationTime,來跳過子樹的遍歷及渲染,本文講下 childExpirationTime 的含義和做用。app

expirationTime 是如何產生的?
每當節點調用setState,就會產生一個update而且計算出一個expirationTime(關於 expirationTime 的計算,請看:React源碼解析之ExpirationTimeoop

childExpirationTime 是如何產生的?post

因爲 React 的更新是從FiberRoot開始的,因此當某一節點發生更新時,React 會向上遍歷,直至找到FiberRoot性能

在向上遍歷的過程當中,會順便找到發生更新節點的父節點,當找到父節點的時候,因爲它們的子節點發生了更新,因此會在父節點上設置childExpirationTime3d

注意:
(1)多個子節點更新,取最大的expirationTime做爲父節點的childExpirationTime
每一個父節點上只會有一個expirationTime和一個childExpirationTime,當有多個子節點都有更新時,取子節點最大的(優先級最高的)expirationTime,做爲父節點的childExpirationTimecode

(2)單個子節點屢次更新,取某次更新出的最大的expirationTime做爲自身的expirationTimecdn

childExpirationTime 的做用?
在 React 自上而下更新 fiber 樹的時候,每一個節點會執行update方法,根據expirationTimechildExpirationTime的優先級大小來判斷該節點自己、該節點的子節點是否須要在本次渲染(這一幀)的時候更新。對象

舉個例子:
上圖的List產生的更新的expirationTime爲 250(假設的,其實是個時間戳),Span1expirationTime爲 100,Span2expirationTime爲 200,明顯 Span2 的優先級高於 Span1,因此ListchildExpirationTime設爲 200blog

其餘節點均無更新,expirationTime=NoWork即 0,當 React 自上而下遍歷到List節點時,發現它的 fiber 對象的expirationTime大於childExpirationTime,因此會優先執行List自身的更新,若是這一幀留給 React 的時間還夠的話,會執行其子節點的更新,不然就跳過,放在下一幀執行rem

能夠想象,若是不設置childExpirationTime的話,還要繼續向下遍歷獲取子節點的expirationTime再拿去跟父節點的expirationTime比較,看誰先更新,是浪費性能的作法。


(完)

相關文章
相關標籤/搜索