react Diff算法
一個頁面就是一個DOM樹,當頁面發生變化的時候,又會形成另一個DOM樹,這兩個樹要作比較的時候,就用到了Diff算法。
傳統的diff算法為O(n^3),相當復雜。
時間復雜度是檢測一個算法或者一個性能好壞的重要因數。
其他它沒有什麽神奇的,只是一個名詞而已。
O(n^3) -> O(n^2) -> O(n)
從左到右,時間復雜度越來越小,越小性能越好。
傳統的diff算法會比較不同,react的diff算法會先檢查結構是否相同,如果不同直接銷毀重建。
react將diff算法從O(n^3) 直接變為 O(n), 大大提高了性能。
-
Web UI 中 DOM 節點跨層級的移動操作特別少,可以忽略不計。
-
擁有相同類的兩個組件將會生成相似的樹形結構,擁有不同類的兩個組件將會生成不同的樹形結構。(類似的虛擬DOM節點,不會作比較,而是直接銷毀之前的DOM節點,然後添加新DOM節點,省去了兩個DOM樹的對比,提高了性能)
-
對於同一層級的一組子節點,它們可以通過唯一 id 進行區分。(即map循環要加key這個唯一標識)
基於以上三個前提策略,React 分別對 tree diff、component diff 以及 element diff 進行算法優化,事實也證明這三個前提策略是合理且準確的,它保證了整體界面構建的性能。
-
tree diff
-
component diff
-
element diff
當一個節點從div變成span時,簡單的直接刪除div節點,並插入一個新的span節點。這符合我們對真實DOM操作的理解。需要註意的是,刪除節點意味著徹底銷毀該節點,而不是再後續的比較中再去看是否有另外一個節點等同於該刪除的節點。如果該刪除的節點之下有子節點,那麽這些子節點也會被完全刪除,它們也不會用於後面的比較。這也是算法復雜能夠降低到O(n)的原因。
React的DOM Diff算法實際上只會對樹進行逐層比較。
參考:
http://www.infoq.com/cn/articles/react-dom-diff/
https://zhuanlan.zhihu.com/p/20346379?refer=purerender
react Diff算法