diff算法


diff算法的作用
計算出Virtual DOM中真正變化的部分,並只針對該部分進行原生DOM操作,而非重新渲染整個頁面。

 

傳統diff算法
通過循環遞歸對節點進行依次對比,算法復雜度達到 O(n^3) ,n是樹的節點數,這個有多可怕呢?——如果要展示1000個節點,得執行上億次比較。。即便是CPU快能執行30億條命令,也 很難在一秒內計算出差異
 

React的diff算法
(1)什么是調和
將Virtual DOM樹轉換成actual DOM樹的最少操作的過程 稱為 調和 。

(2)什么是React diff算法?
diff算法是調和的具體實現。

diff策略
React用 三大策略 將O(n^3)復雜度 轉化為 O(n)復雜度

策略一(tree diff):
Web UI中DOM節點跨層級的移動操作特別少,可以忽略不計。

策略二(component diff):
擁有相同類的兩個組件 生成相似的樹形結構,
擁有不同類的兩個組件 生成不同的樹形結構。

策略三(element diff):
對於同一層級的一組子節點,通過唯一id區分。


tree diff

 

 如果DOM節點出現了跨層級操作,diff會咋辦呢?

答:diff只簡單考慮同層級的節點位置變換,如果是跨層級的話,只有創建節點和刪除節點的操作。

 

 如上圖所示,以A為根節點的整棵樹會被重新創建,而不是移動,因此 官方建議不要進行DOM節點跨層級操作,可以通過CSS隱藏、顯示節點,而不是真正地移除、添加DOM節點。

 

component diff
React對不同的組件間的比較,有三種策略
(1)同一類型的兩個組件,按原策略(層級比較)繼續比較Virtual DOM樹即可。

(2)同一類型的兩個組件,組件A變化為組件B時,可能Virtual DOM沒有任何變化,如果知道這點(變換的過程中,Virtual DOM沒有改變),可節省大量計算時間,所以 用戶 可以通過 shouldComponentUpdate() 來判斷是否需要 判斷計算。

(3)不同類型的組件,將一個(將被改變的)組件判斷為dirty component(臟組件),從而替換 整個組件的所有節點

注意:如果組件D和組件G的結構相似,但是 React判斷是 不同類型的組件,則不會比較其結構,而是刪除 組件D及其子節點,創建組件G及其子節點。

 

 

element diff
當節點處於同一層級時,diff提供三種節點操作:刪除、插入、移動

插入:組件 C 不在集合(A,B)中,需要插入

刪除:(1)組件 D 在集合(A,B,D)中,但 D的節點已經更改,不能復用和更新,所以需要刪除 舊的 D ,再創建新的。

(2)組件 D 之前在 集合(A,B,D)中,但集合變成新的集合(A,B)了,D 就需要被刪除。

移動:組件D已經在集合(A,B,C,D)里了,且集合更新時,D沒有發生更新,只是位置改變,如新集合(A,D,B,C),D在第二個,無須像傳統diff,讓舊集合的第二個B和新集合的第二個D 比較,並且刪除第二個位置的B,再在第二個位置插入D,而是 (對同一層級的同組子節點) 添加唯一key進行區分,移動即可。

 

 

轉https://www.jianshu.com/p/3ba0822018cf


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM