react diff算法為降低算法復雜度提出了三大策略:
1.只進行同級比較
2.節點類型比較,不同元素生成不同的fiber樹
3.key作為元素的唯一標識
diff算法流程
diff算法需要進行兩輪遍歷:
第一輪遍歷更新的節點。
第二輪遍歷沒更新的節點。
第一輪:
從頭遍歷newChildren對象和老的fiber樹。如果節點key不同,則不可復用,第一輪遍歷結束。若key相同,但元素類型不同,oldfiber標記為delete,繼續遍歷。
第一輪遍歷完有四種情況:
1.newChildren 與 oldFiber 同時遍歷完
理想情況:只需在第一輪遍歷進行組件更新,diff結束
2.newChildren 沒遍歷完,oldFiber 遍歷完
本次更新有新加入的節點
3.newChildren 遍歷完,oldFiber 沒遍歷完
有節點被刪除
4.newChildren 與 oldFiber 都沒遍歷完
有節點更新了位置,通過oldfiber生成一個map,map的key為oldfiber的key,oldfiber為value。遍歷剩余的newChildren,(lastPlacedIndex 是最后一個可復用的節點在 oldFiber 中的位置索引)逐個在 map 中尋找 oldFiber 中可復用的節點,如果找到可復用的節點,則將 oldIndex 與 lastPlacedIndex 比較,如果 oldIndex 與 lastPlacedIndex 小,則該節點需要右移,將新的 Fiber 節點標記為 Placement 。否則,將 lastPlacedIndex 更新為 oldIndex 。
遍歷完新的子元素,map中還有剩余節點,則刪除。