標籤:16px 時間複雜度 div lan 不同 image 最佳化 操作 刪除節點
一個頁面就是一個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演算法