第十章 双端diff算法

100 阅读2分钟

双端diff 算法

  1. 简单diff算法从一端开始处理; 简单diff算法能够实现 dom 节点的复用,但有的时候会做一些没必要的移动。
  2. 双端diff算法是一种同时对新旧vnode的两个端点进行比较的算法。它的优势在于比起简单Diff算法,可以减少DOM移动次数。

双端 diff 需要 4 个指针,分别指向新旧两个 vnode 数组的头尾: t-diff01.png

双端 diff 是头尾指针向中间移动的同时,对比(新旧VNode的顺序)头头、尾尾、头尾、尾头是否可以复用,如果可以的话就移动对应的 dom 节点。 t-diff02.png

  • 上图的p4匹配成功, 可以移动到节点的最前面, 移动完成后对应指针移动 如下图: t-diff03.png

  • 上图P3匹配成功,都在为尾尾,不用移动, 指针双双上移动,如下图: t-diff04.png

上图,先匹配到p1, p1下移,移动完成, 指针移动,如下图: t-diff05.png

上图,新旧vnode的头/尾索引发生重合,首尾指针相等,不满足循环条件,则自动结束。若仍然满足循环条件,所以还会进行下一轮更新。 t-diff06.png

上图, 非理想情况, 如果头尾没找到可复用节点就遍历 vnode 数组来查找,然后移动对应下标的节点到头部。当尝试按照双端diff算法思路进行第一轮比较时,会发现无法命中四个步骤中的任何一步。只能通过额外增加的处理步骤来处理这种非理想情况。即,拿新vnode的头部节点去旧vnode的一组子节点中寻找

t-diff07.png t-diff08.png

上图:新增标签的过程; 最后还剩下旧的 vnode 就批量删除,剩下新的 vnode 就批量新增

t-diff09.png t-diff10.png

  • 上图是移除DOM的过程, 指针从两端向中间移动,情况如下:
  1. 满足更新停止的条件。旧vnode中还存在未被处理的节点,应该将其移除.
  2. 满足更新停止的条件。新vnode中还存在未被处理的节点,应该将其添加.