【前端每天一题】🔥 第 24 题:Virtual DOM 中 diff 算法的核心流程(详细版

第 24 题:Virtual DOM 中 diff 算法的核心流程(详细版)

下面是详细讲解(不画图、不引用图片):


24. Virtual DOM 的 Diff 算法核心流程(详细版)

Diff(差异对比)算法是 Virtual DOM 的核心,用来比较新旧两棵虚拟 DOM 树的不同,最终只把差异更新到真实 DOM,从而提升性能。

以下分 6 个步骤讲清楚整个流程:


① 第一层优化:同层比较,不跨层

虚拟 DOM 永不跨层比较:

  • 旧树第 1 层只对比新树第 1 层
  • 旧树第 2 层只对比新树第 2 层
  • ......

原因: 浏览器真实 DOM 结构很少跨层变动,所以避免跨层,大幅减少计算量。


② 第二层优化:节点类型不同 → 整个节点直接替换

判断两个节点是否"同类型",主要看:

判断内容 示例
标签是否相同 div → div
组件是否相同 MyComponent → MyComponent
key 是否一致 key="1" → key="1"

如果节点类型不同直接整棵替换:

css 复制代码
<div> → <span>

不用再继续往下比较 children。


③ 节点类型相同 → 继续比较属性(props)

例如两个 div:

ini 复制代码
<div id="a" class="x">
<div id="b">

Diff 会:

  1. 找出删除的属性
  2. 找出新增的属性
  3. 找出修改的属性

最终生成类似补丁:

kotlin 复制代码
PATCH {
  remove class
  update id: a → b
}

④ 比较 Children(最复杂的部分)

子节点可能会:

  • 增加
  • 删除
  • 移动
  • 更新内容

其中列表渲染 v-for 的 diff 最复杂,需要 key。

Vue Diff 对 children 会做三类操作:


(1)同位置比较(前置指针)

从左往右一个一个比:

旧:A B C D

新:A B E D

前两个一致,跳过

到第三个不一致,执行更新


(2)尾部比较(后置指针)

从右往左比:

旧:A B C D

新:E B C D

尾部 D、C、B 都一样

只需处理最前面的 A 、E。

这种前后双指针优化减少很多循环。


(3)核心:key 的最长递增子序列(LIS)优化移动

这是最精华部分。

举例:

旧节点:A B C D

新节点:B A D C

为了尽量减少"移动 DOM 次数",Vue 会:

  1. 先计算每个旧节点在新列表中的下标映射。
  2. 找出最长递增子序列(LIS),这些节点不动。
  3. 剩下的节点才需要移动。

这样 DOM 操作最少,性能最好。


⑤ 生成补丁(patch)列表

patch 列表包含:

  • 哪些节点要删除
  • 哪些要新增
  • 哪些要移动
  • 哪些属性要更新
  • 哪些文本要替换

最终所有操作都是对真实 DOM 的最小修改集。


⑥ 执行 patch,更新真实 DOM

最后一步由渲染器完成:

  • 删除 DOM
  • 插入 DOM
  • 更新属性
  • 设置文本内容
  • 移动节点位置

这一步才真正发生浏览器的重绘/回流。


总结(背诵用)

Diff 算法核心 6 步:

  1. 同层对比,不跨层
  2. 节点类型不同 → 整个替换
  3. 节点类型相同 → 更新属性
  4. 比较 children:前置/后置/Key+LIS
  5. 生成最小修改补丁(patch)
  6. 执行 patch 更新真实 DOM

如果你要,我可以继续:

✅ 用图示方式讲

✅ 用代码模拟一次完整的 diff 流程

✅ 用实际 Vue 代码展示 diff 如何触发

你要哪个?

相关推荐
Highcharts.js12 分钟前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
薛定谔的猫-菜鸟程序员36 分钟前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron
最强小杰1 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
考研保研资料分享1 小时前
2022环境工程保研北师大:三校专业追问、论文贡献与择校复盘
面试
静水leo1 小时前
使用 Whistle 拦截接口并模拟后端响应
前端
掘金者阿豪2 小时前
SQL Server数据迁移完成后,凌晨的数据库告警该怎么查?
前端·后端
JudithHuang2 小时前
React 嵌套路由与布局
前端·react.js·arcgis·react·react router
htzyl2062 小时前
前端阶梯——第四十三章、实战二:待办清单To-Do
前端·javascript·html
摹客3 小时前
【3D设计】界面设计中的3D元素:应用场景+5款工具横评(含Three.js)
前端