DOM diff
- 利用创建对象的方法,在内存中创建一个与真实节点结构相同的虚拟节点对象。
- 再创建一个将要改变的虚拟节点对象
- 比较两个虚拟节点的区别,产生petch补丁包
- 将补丁替换在真实节点上。
DOM diff的优化策略
- 同级比较
- 不进行跨级比较,如果同一级没有相同节点,则删除对应节点
- 如果同级节点换位,则只改变对应位置,不操作其他节点,节省资源
差异计算
dom树先序遍历(根左右),深度优先
平级元素换位置使用appendChild,replaceChild,具有移动性,dom的重定位,不重新渲染
react diff算法
- lastIndex指针,依次遍历新dom树中的节点,找到一个节点后,mountIndex在旧dom数中从左到右遍历节点,寻找key相同的节点,如果mountIndex >= lastIndex的值,则不移动,lastIndex = mountIndex
(旧节点在新节点右边的话就不动)lastIndex 右移,自增1 - 如果mountIndex < lastIndex的值,将旧节点移动至lastIndex的位置,
lastIndex 右移,自增1,循环继续 - 如果旧节点中没有这个新节点,则将新节点添加至lastIndex的位置
- lastIndex遍历完成后,将右边剩余节点删除
缺点,尽量不要将最后一个节点移动到第一个节点,会很耗费资源,
abcd变为dabc会将d不动,abc每个都移动
mountIndex
a,b,c,d,f
0
lastIndex
b,e,a,d,c
0
第一轮
mountIndex
a,b,c,d,f
0,1
lastIndex
b,e,a,d,c
1b不动
第二轮
mountIndex
a,b,e,c,d,f
0,1,2
lastIndex
b,e,a,d,c
1,2在2的位置添加e
第三轮
mountIndex
b,e,a,c,d,f
1,2,3
lastIndex
b,e,a,d,c
1,2,3把a移到3
第四轮
mountIndex
b,e,a,c,d,f
1,2,3,4,5
lastIndex
b,e,a,d,c
1,2,3,5d不动
第五轮
mountIndex
b,e,a,d,c,f
1,2,3,5,6
lastIndex
b,e,a,d,c
1,2,3,5,6c放到6的位置
第六轮
mountIndex
b,e,a,d,c
1,2,3,5,6
lastIndex
b,e,a,d,c
1,2,3,5,6lastIndex遍历完了,删除6之后的节点