diff算法流程

609 阅读4分钟

diff算法流程

image.png

  1. 调用patch,判断旧节点是否是虚拟节点 ,不是虚拟节点,该为虚拟节点,判断旧节点与新节点是否是同一个sel和key,不是同一个sel和key删除旧节点,插入新节点
  2. 调用patch,判断旧节点是否是虚拟节点 ,是虚拟节点,判断旧节点与新节点是否是同一个sel和key,是同一个sel和key,判断·旧节点与新节点是否是同一个对象,是同一个对象不操作,不是同一个对象,判断新节点有无text,有text,判断text是否相同,text相同不操作;text不相同,直接把elm.textContent改为新节点的text
  3. 调用patch,判断旧节点是否是虚拟节点 ,是虚拟节点,判断旧节点与新节点是否是同一个sel和key,是同一个sel和key,判断·旧节点与新节点是否是同一个对象,是同一个对象不操作,不是同一个对象,判断新节点有无text,无text,判断旧节点有无children,无children,说明旧节点只有text,我们直接改为新节点中的children; 有children,说明双方都有children我们需要使用diff进行比较
  4. 新增情况

旧节点有旧前,旧后;新节点有新前,新后,新前和旧前自上而下;新后和旧后自下而上

在这里要使用4个指针,从1-4的顺序来开始命中优化策略,命中一个,指针进行移动(新前和旧前自上而下;新后和旧后自下而上),没有命中,就使用下一个策略,如果四个策略都没有命中,只能靠循环来找

命中:两个节点sel和key一样

image.png

有四种策略:1,新前与旧前2,新后与旧后3,新后与旧前4,新前与旧后

新增情况 image.png

1)使用第一种策略,新前与旧前

A命中,指针进行移动,继续向下

B命中,指针进行移动,,继续向下

c命中,指针进行移动,,继续向下,旧前在旧后的后面结束循环,新前与新后之间包含新后,就是新增节点

删除情况1 image.png

A命中,指针进行移动,,继续向下

B命中,指针进行移动,,继续向下

D没命中,换策略但是新前,旧前,新后,旧后位置不可变动,换新后与旧后策略

D命中,移动指针,新后在新前的前面结束循环,旧前与旧后指向一致的就是删除的节点

删除情况2

image.png

A命中,指针进行移动,继续向下

B命中,指针进行移动,继续向下

D没命中,换策略,换新后与旧后策略,依旧没命中;换策略,换新后与旧前,依旧没命中;

换策略,换新前与旧后,依旧没命中;循环找到D,新节点命中,指针移动,循环结束,在真实的DOM是移动到B之后,在虚拟DOM中把他标为undefined。旧后旧前之间就是要删除的节点C,E

复杂情况1

image.png

E,新前与旧前策略,没命中;换策略,换新后与旧后 ,没命中; 换策略,换新后与旧前 ,没命中;

换策略,换新前与旧后 ,命中,这里在虚拟DOM旧后指向的设置为undefined,实际DOM已经把新前指向的节点移动到旧前之前,指针移动,新前向下移动,旧后向前移动,

C,没命中,四种策略都每命中,靠循环旧节点来查找C,找到C把它标记为undefined,并把它插入到旧节点之前

k,新前移动是因为它通过while命中了,旧节点不用移动,k,四种策略都每命中,while

也没有在旧节点中找到,直接把前的k移动到旧前之前,循环结束,旧前和旧后之间的节点

将被删除A,B,D

复杂情况2

image.png

C,前两中策略都没有命中,第三中策略新后与旧后,命中了,指针移动,

B,命中了,指针移动

A,命中了,指针移动,循环结束