【前端每天一题】🔥 第 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 如何触发

你要哪个?

相关推荐
梦想的旅途214 小时前
企业微信API实战:Python自动化消息推送
java·前端·python·自动化·企业微信
恋猫de小郭14 小时前
Flutter 3.47 发布,快来看看有什么更新吧
android·前端·flutter
程序员黑豆14 小时前
Java 内存存储机制:基本数据类型 vs 引用数据类型
前端·ai编程·全栈
程序员爱钓鱼14 小时前
Go 运算符详解
后端·面试·go
90后的晨仔14 小时前
uni-app 三方库与插件管理体系全解析:从原生开发者视角彻底讲透
前端
程序员爱钓鱼14 小时前
Rust 生命周期案例详解:从编译错误到真实业务场景
前端·后端·rust
90后的晨仔15 小时前
uni-app 跨端布局与适配技术指南
前端
rannn_1111 天前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
紫禁玄科1 天前
Shai-Hulud:npm生态的自我复制蠕虫风暴
前端·npm·node.js
东风破_1 天前
后端API没写好,前端难道干等着吗?
前端