Vue2 的 diff 算法原理

diff 的时机

当组件创建、以及依赖的属性或数据变化从而运行_update()函数时。

_update 的作用

  1. 接收一个vnode参数,即新的 vnode。
  2. 同时通过当前组件的_vnode属性拿到旧的 vnode。
  3. 将新的 vnode 赋值给 _vnode 属性。
  4. 判断旧的 vnode 是否存在:
    • 不存在则调用patch函数遍历新的 vnode 为每个节点创建真实 DOM,并挂载到每个节点的ele属性上。
    • 存在则通过 patch 函数对新旧 vnode 进行对比,让新 vnode 的每个节点的 ele 属性匹配到合适的真实 DOM,并以最小代价完成真实 DOM 处理。

patch 函数的运行流程

主要是通过同时满足以下 3 个条件判断两个虚拟节点是否相同(相同三要素):

  1. 标签类型tag是否相同
  2. key值是否相同
  3. 如果是 input 元素, type 属性是否相同

对比过程总结为深度优先,同层对比,即先将当前节点及其子节点对比完,再从同层节点寻找下个对比对象,详细流程:

  1. 根节点比较

    • 若相同,则开始更新,将旧节点的真实 dom 赋值给新节点的 ele 属性,对比新旧节点的属性,将变化更新到真实 dom 中,当前两个节点处理完毕后开始对比子节点。
    • 若不相同,则新节点递归创建真实 dom,旧节点销毁 ele 属性,即销毁旧的真实 dom。
  2. 对比子节点,大致与上述对比相同,通过以下方面进行对比效率提升

    • 优先只改动真实 dom 元素属性
    • 其次移动元素以替代创建和删除元素
    • 最后才考虑创建和删除元素

子节点对比细节

vue 对新旧 vnode 生成了新旧两个子节点数组,并对两个数组同使用两个指针,分别指向各自数组的头和尾,然后不断向数组中间靠拢来一一对比:

若新旧数组的头或尾指针所指向的节点相同(相同三要素),则只改动真实 dom 元素的属性差异,同时当前两个指针移动。

若不同则从旧数组中寻找所有与当前新数组头指针相同的节点,若还没找到,则创建元素,同时新数组头或尾指针移动,进行下一轮对比...当新数组头指针超过尾指针,循环结束,没有被匹配到的旧数组会被遍历删除元素。

就这样一直递归遍历下去,直到整颗新的 vnode tree 对比完成,之后旧的 vnode 所占用的内存空间则会被垃圾回收。

相关推荐
崔庆才丨静觅12 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606113 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了13 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅13 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅14 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅14 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment14 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅14 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊15 小时前
jwt介绍
前端
爱敲代码的小鱼15 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax