虚拟 DOM 中的 Diff 算法

  • 查找两颗树的每一个节点的差异

Diff-01.png
Snabbdom 根据 DOM 的特点对传统的 Diff 算法做了优化

  • DOM 操作时候很少会跨级别操作节点
  • 只比较同级别的节点

Diff-02.png
执行过程:

  • 在对开始节点和结束节点比较的时候,总共有四种情况
    • oldStartVnode / newStartVnode(旧开始节点/新开始节点)
    • oldEndVnode / newEndVnode(旧结束节点/新结束节点)
    • oldStartVnode / newEndVnode(旧开始节点/新结束节点)
    • oldEndVnode / newStartVnode(旧结束节点/新开始节点)

Diff-03.png

开始和结束节点

  • 如果新旧开始节点是 sameVnode(key和 sel相同)
    • 调用 patchVnode() 对比和更新新节点
    • 旧节点和新开始索引往后移动 oldStartIdx++ / oldEndIdx++

Diff-04.png

旧开始节点 / 新结束节点

  • 调用 patchVnode() 对比和更新节点
  • 把 oldStartVnode 对应的 DOM 元素,移动到右边,更新索引

Diff-05.png

旧结束节点 / 新开始节点

  • 调用 patchVnode() 对比和更新节点
  • 把 oldEndVnode 对应的 DOM元素,移动到左边,更新索引

Diff-06.png

非以上四种情况

Diff-07.png

循环结束

  • 当老节点的所以子节点先遍历完(oldStartIdx > oldEndIdx)
    • 说明新节点有剩余,把剩余节点批量插入到右边

Diff-08.png

  • 新节点的所以子节点先遍历完(newStartIdx > newEndIdx)
    • 说明老节点有剩余,把剩余节点批量删除

Diff-09.png