1 流程概览
-
一个DOM节点最多会有四个节点与之关联,如下图:
-
React在Diff算法的优化:
- 只对同级元素进行Diff。如果一个DOM节点在前后两次更新中跨越了层级,则不再复用他;
- 类型不同时会销毁它及其子节点再新建;(如下面的p和span都会销毁再新建)
<div>
<p>p节点</p>
<span>span节点</span>
</div>
//更新为 ↓
<div>
<span>span节点</span>
<p>p节点</p>
</div>
- 设置key值可告诉react哪些可复用。(如下例子只会交换p和span的顺序)
<div>
<p key="p">p节点</p>
<span key="span">span节点</span>
</div>
//更新为 ↓
<div>
<span key="span">span节点</span>
<p key="p">p节点</p>
</div>
- Diff的入口
在reconcileChildFibers(returnFiber,currentFirstChild,newChild)内会根据newChild(返回的jsx对象)的类型(object,array等)选择不同的处理函数。
2 单一节点的Diff
以Object类型为例,会进入reconcileSingleElement方法
3 多节点的diff
- 当child存在多个同级节点时,如下面的div的子节点:
<div>
<p>p节点</p>
<span>span节点</span>
</div>
- 前后变化有以下三种情况:
- 节点更新(包括属性和类型)
- 节点新增或减少
- 节点位置变换
- diff的思路
- 因为更新的频率比新增或删除高,且要对比的newChildren和curretFiber一个是数组一个是链表,无法使用双指针遍历,所以react团队将整个diff算法分成了两轮遍历:
- 处理更新的节点 --> 处理剩下的不属于更新的节点
- 流程图
- 较为复杂,正在学习...