Vue3-快速diff算法

228 阅读2分钟

Vue2-双端Diff算法

引入:为了提升性能,尽量去复用节点,减少DOM操作,那么就需要diff算法。

精读《Vuejs设计与实现》第 10 章(双端 diff 算法)

简述流程

  1. 头尾节点间的比较:头头-尾尾-尾头-头尾 image.png
  2. 非理想情况 image.png
  • 拿着新头去旧数组里找
    1. 找到了,放到真实DOM的头部
    2. 找不到,新增该节点;
  • 如果oldIdx不符合要求了,检查newIdx,继续新增节点
  1. 意味着newIdx不满足条件,而oldIdx满足,则需要移除不存在元素。

Vue3-快速diff算法

引入

image.png 上图来自js-framework-benchmark,从中可以看出,在DOM操作的各个方面,ivi和inferno所采用的快速 Diff算法的性能都要稍优于 Vue.js2所采用的双端Diff算法。

去除相同的前置元素和后置元素

image.png

判断是否需要进行 DOM 移动操作

在循环中加入了pre(number)和move(boolean),分别代表前一次循环中最大的索引,以此判断出是否要移动; image.png

  • 规律:遍历过程中遇到的索引值呈现递增趋势,则说明不需要移动节点,反之则需要。
  • 对于最后一个for循环,i代表的是oldVNode在旧数组中的索引;k代表该节点在新数组中的索引。 pos一直记录的是遇到的最大的k。 image.png 解释其含义 image.png

如何移动元素

  1. 以新子节点剩余的个数,创建一个source数组,所有初值为-1;存储当前节点在旧子节点中的索引;其中source的key代表新子节点数组的索引,value代表对应节点在旧子节点中的索引。 image.png
  2. 计算source数组的最长递增子序列。

toutiao.io/posts/9vvtg…

image.png

Vue3快速Diff算法中的最长递增子序列算法详解 juejin.cn/post/721141…

  1. 三种情况
  • 代码 image.png image.png
  • 详解 新增 image.png 需要移动 image.png image.png image.png 不用操作 image.png image.png image.png