聊一聊diff算法,谈谈我的理解

69 阅读1分钟

虚拟dom是在vue1更新至vue2时引入的新特性,目的是实现跨平台,虚拟dom是描述dom的对象,在那个环境都可以使用,只需要根据环境提供不同的渲染方法,而vue1是直接操作dom,与浏览器环境深度绑定,无法在Android等环境中使用
既然有了虚拟dom,那必然需要涉及到虚拟dom的更新,就需要用到diff算法来优化更新的过程

在dom更新之后,会重新执行render函数,产生新的Vnode,此时需要对比新旧Vnode,找出不同部分,并更新到真实dom上,这时就是使用diff算法对比,diff是difference的简写,简单来说就是找不同的深度优先算法,它默认的对比顺序是:
if (头和头比) {}
else if (尾和尾比) {}
else if (头和尾比) {}
else if (尾和头比) {}
image.png 这里条件判断用了sameVnode函数

image.png

这里看到 key 作用于 diff算法的 sameVnode 函数中,key相同,会递归对比子节点,在发现key值不同,会被短路与直接跳过内容和子节点递归对比部分,这就是为什么要强调设置key值

如果对比相等,则执行patchVnode,并将指针按当前对比方式进行移动,即
头和头比: 将新旧Vnode的头指针后移
尾和尾比: 将新旧Vnode的尾指针前移
头和尾比: 将旧Vnode的头指针后移,新Vnode的尾指针前移
尾和头比: 将旧Vnode的尾指针前移,新Vnode的头指针后移

如果对比不同,则更新dom

注意,key值更变,diff算法一定会更新dom,我们可以利用这个特性强制更新dom