傳統diff 通過迴圈遞歸對節點的依次對比,複雜度是O(n3) react diff react對傳統diff進行了優化,將複雜度降為O(n) react基於這幾個前提對diff進行了優化: 忽略跨層級操作,因為DOM節點跨層級操作很少。 不同類的組件,則會生成不同的樹形結構,相同類的組件,會生成相 ...
傳統diff
通過迴圈遞歸對節點的依次對比,複雜度是O(n3)
react diff
react對傳統diff進行了優化,將複雜度降為O(n)
react基於這幾個前提對diff進行了優化:
- 忽略跨層級操作,因為DOM節點跨層級操作很少。
- 不同類的組件,則會生成不同的樹形結構,相同類的組件,會生成相似的樹形結構。
- 對同一層級的一組子節點,可以通過唯一key進行區分。
1 tree diff
只會對相同層級的DOM節點進行比較,只需要一次遍歷,便可以完成整棵樹的遍歷。如果節點不存在,則該節點及其子節點都會被刪掉,對於不同層級的節點,只有創建和刪除操作。
2 component diff
- 針對同類型組件,按照tree diff策略對比。如果開發人員確切知道virtual DOM沒有變化,react提供的
shouldComponentUpdate()
方法可以直接省去tree diff。 - 針對不同類型組件,則直接判斷該組件為dirty component,從而替換整個組件下的所有子節點。
3 element diff
當節點處於同一層級,可能除夕只需要對這些節點進行移動,不需要每次都刪除創建,react剔除添加唯一key來區分。react通過判斷key是否存在相同節點,如果存在,再進行判斷進行移動操作。不存在再進行相應的創建刪除。
與vue的diff區別
- 判斷2個節點是否相同:vue認為className不一樣,就不同,react則認為相同,只是屬性不同,只需要更新其屬性。
- 同一層級對比:Vue從兩端至中間對比,react從左至右對比。react策略存在短板,如果一個集合只吧最後一個移到第一個,react會移動前面所有節點,vue只移動最後一個節點到最前面。