《Vuejs设计与实现》10.1 双端比较的原理(上)

102 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

前面我们看完了简单的diff算法,这个简单指的是算法比较简单,只是通过key去比较,尽量不删除和新增DOM,只移动DOM.但这样的diff算法并不能满足vue的需要,我们需要效率更高的算法,因此本章就是新的diff算法,名字叫做《双端比较算法》

image.png

我们举一个简单的例子,如图上所示,我们可以发现,只有p3节点发生了移动,从底部移动到了顶部,理论上只需要移动一次就可以完成这次diff操作,但是我们之前的算法,同时遍历新旧列表,则需要移动2次。这就是为什么被叫做简单的diff算法。

双端比较算法

双端比较算法顾名思义,就是从列表的两头的同时去对比,因为我们有2个节点,一个新节点列表,一个旧节点列表,因此我们需要需要保存4个位置变量

image.png

在双端比较中,每一轮比较都分为四个步骤(我们假设新节点列表为B列表,旧节点列表为A列表):

  • 比较 A 的第一个子节点 与 B 的第一个子节点
  • 比较 A 的最后一个子节点 与 B 的最后一个子节点
  • 比较 A 的第一个子节点 与 B 的最后一个子节点
  • 比较 A 的最后一个子节点 与 B 的第一个子节点

当我们这样比较完一轮之后,我们发现旧节点A 的最后一个子节点 变成了节点列表B 的第一个子节点,因此我们就可以去移动了,这样只需要移动一次,移动的方法无需赘述,无法还是insertBefore或者insertAfter

更为重要的时候,我们需要更新这4个位置变量,以防止出现下一次循环遍历