《Vue3 从入门到大神26篇》Virtual DOM 与 Diff 算法 —— Vue3 的高效更新机制 前言这一篇我们来了解vue3高效更新机制的核心逻辑很多人对 Virtual DOM虚拟 DOM有一个误解❌ “Virtual DOM 比原生 DOM 快。”这是一个伪命题。事实上操作 Virtual DOM 本身也有成本它之所以能提升性能是因为它能计算出最小更新量从而减少昂贵的 DOM 操作。而 Vue3 的 Diff 算法正是为了尽可能少地操作 DOM。这一篇我们系统讲解✅ 什么是 Virtual DOM✅ VNode 的设计✅ Vue3 的 Diff 策略✅ 最长递增子序列LIS在 Diff 中的作用✅ 为什么 Vue3 的 Diff 更快一、为什么需要 Virtual DOM1️⃣ 原生 DOM 的问题document.getElementById(app).innerHTML div p${count}/p buttonClick/button /div ❌ 问题DOM 操作非常昂贵重排、重绘每次更新都重新创建所有 DOM无法复用已有 DOM2️⃣ Virtual DOM 的核心思想数据变化 ↓ 生成新的 Virtual DOMJS 对象 ↓ Diff 对比新旧 VDOM ↓ 计算出最小变更 ↓ 只更新必要的真实 DOMVirtual DOM 是“中间层”不是“性能银弹”。二、VNodeVirtual DOM 的基本单元1️⃣ VNode 是什么interface VNode { type: string | object | null // 标签名 / 组件对象 props: Recordstring, any | null children: VNode[] | string | null el: HTMLElement | null // 对应的真实 DOM key?: string | number }2️⃣ 一个真实 VNode 示例const vnode { type: div, props: { class: container }, children: [ { type: p, props: null, children: Hello Vue3 } ], el: null }3️⃣ h 函数创建 VNode 的工具function h(type, props, children) { return { type, props, children, el: null } } // 使用 h(div, { class: container }, [ h(p, null, Hello Vue3) ])Vue 模板编译后最终都会变成h()调用。三、Diff 算法找出差异1️⃣ Diff 的本质给定两棵树旧 VDOM 和新 VDOM找出最小的修改操作。这是一个经典的树编辑距离问题理论上时间复杂度是O(n³)。Vue 做了一个重要假设只比较同一层级的节点不跨层级比较。这样时间复杂度降到了O(n)。2️⃣ Vue2 的双端 DiffVue2 使用的是双端比较算法旧[a, b, c, d] 新[b, c, e, d]比较流程旧头 vs 新头旧尾 vs 新尾旧头 vs 新尾旧尾 vs 新头✅ 优点逻辑直观❌ 缺点移动节点时不够高效四、Vue3 的 Diff更聪明的策略Vue3 在双端比较的基础上引入了最长递增子序列LIS优化。1️⃣ 核心思路1. 预处理处理相同的前缀和后缀 2. 构建 key - index 映射表 3. 找出最长不需要移动的节点序列 4. 只移动必要的节点2️⃣ 示例为什么要 LIS!-- 旧 VDOM -- ul li keyaA/li li keybB/li li keycC/li li keydD/li /ul !-- 新 VDOM -- ul li keybB/li li keycC/li li keyeE/li li keydD/li /ul变化A 被删除E 被插入B、C、D 顺序变化3️⃣ 最长递增子序列的作用Vue3 会找出在新旧 VDOM 中相对位置不变的节点序列旧索引 [0, 1, 2, 3] (a, b, c, d) 新索引 [1, 2, 3, 0] (b, c, d, a) 最长递增子序列 [1, 2, 3] → 对应 b, c, d结论b、c、d 这三个节点不需要移动只需要移动其他节点。五、LIS 算法简化实现function getLIS(arr) { const dp new Array(arr.length).fill(1) let maxLen 1 for (let i 1; i arr.length; i) { for (let j 0; j i; j) { if (arr[i] arr[j]) { dp[i] Math.max(dp[i], dp[j] 1) } } maxLen Math.max(maxLen, dp[i]) } // 回溯构造 LIS const lis [] for (let i arr.length - 1; i 0; i--) { if (dp[i] maxLen) { lis.unshift(i) maxLen-- } } return lis } // 示例 console.log(getLIS([1, 2, 3, 0])) // [0, 1, 2]Vue3 使用的是 O(n log n) 的贪心算法版本这里为了直观用了 O(n²)。六、Vue3 Diff 的核心优势对比项Vue2Vue3比较策略双端比较双端 LIS移动节点频繁移动最小化移动性能较好更好复杂度O(n)O(n)常数更小Vue3 的 Diff 不是更快而是更少移动 DOM。七、PatchFlags 与 Diff 的关系还记得第 22 篇讲的 PatchFlags 吗// 编译后的渲染函数 _createElementVNode(p, null, _toDisplayString(_ctx.count), 1 /* TEXT */)PatchFlags 是 Diff 的上游优化PatchFlags 告诉 Diff这个节点只有文本变化Diff 就只更新文本内容不再递归比较子节点✅两者结合效果翻倍。八、手写一个简化的 Diff理解版function diff(oldChildren, newChildren, container) { const oldKeyToIndex {} oldChildren.forEach((child, i) { oldKeyToIndex[child.key] i }) const newIndices new Array(newChildren.length).fill(-1) // 建立新节点到旧节点的映射 newChildren.forEach((child, i) { const oldIndex oldKeyToIndex[child.key] if (oldIndex ! undefined) { newIndices[i] oldIndex } }) // 计算 LIS const lis getLIS(newIndices) // 逆序遍历移动节点 let j lis.length - 1 for (let i newChildren.length - 1; i 0; i--) { const newChild newChildren[i] const oldIndex newIndices[i] if (oldIndex -1) { // 新增节点 mount(newChild, container) } else { if (i ! lis[j]) { // 需要移动 move(newChild, container) } else { // 不需要移动 j-- } } } }九、面试高频问答Q1Virtual DOM 一定比原生 DOM 快吗不一定。VDOM 的优势在于减少 DOM 操作次数而不是操作本身更快。Q2Vue3 的 Diff 和 Vue2 有什么不同Vue3 在双端比较基础上引入 LIS最小化节点移动次数。Q3LIS 在 Diff 中的作用是什么找出不需要移动的节点序列只移动必要的节点。十、总结原理级Virtual DOM 是描述 UI 的 JS 对象Diff 的目标是最小化 DOM 操作Vue3 的 Diff 双端比较 LISPatchFlags 是 Diff 的上游优化少移动 DOM才是真正的快 下期预告第 27 篇编译时优化揭秘 —— Vue 模板是如何变成 JS 代码的

相关新闻

最新新闻

PHP 文件包含防御指南:从 iwebsec 靶场看 5 种常见过滤绕过与安全加固

PHP 文件包含防御指南:从 iwebsec 靶场看 5 种常见过滤绕过与安全加固

PHP 文件包含漏洞深度防御:从 iwebsec 靶场实战到企业级安全方案1. 文件包含漏洞的本质与危害文件包含漏洞(File Inclusion Vulnerability)是 Web 应用中最危险的高危漏洞之一。当开发者使用include、require等函数动态加载文件时&#xff0c…

2026/7/8 20:30:30
AI 搜索新风口!好客搜智搜 GEO 代理招商,抢占大模型千亿流量赛道

AI 搜索新风口!好客搜智搜 GEO 代理招商,抢占大模型千亿流量赛道

2026 年互联网营销赛道迎来颠覆性变革,用户不再主动百度搜索,而是直接向豆包、文心一言、DeepSeek 等大模型提问解决方案,传统竞价、SEO 流量持续萎缩,而 GEO 生成式引擎优化开辟全新获客赛道,市场规模连年暴涨&#x…

2026/7/8 20:30:30
PHP 文件包含漏洞实战:iwebsec 靶场 10 关核心利用手法与 3 类伪协议解析

PHP 文件包含漏洞实战:iwebsec 靶场 10 关核心利用手法与 3 类伪协议解析

PHP 文件包含漏洞实战:iwebsec 靶场 10 关核心利用手法与 3 类伪协议解析 在 Web 安全领域,文件包含漏洞(File Inclusion Vulnerability)一直是渗透测试中的高频攻击点。iwebsec 靶场作为国内知名的 Web 安全实战平台,…

2026/7/8 20:30:30
Frida/Objection 实战:Hook 3类SSL Pinning方法(JustTrustMe替代方案)

Frida/Objection 实战:Hook 3类SSL Pinning方法(JustTrustMe替代方案)

Frida/Objection 实战:手动Hook 3类SSL Pinning实现 在移动安全测试中,SSL Pinning(证书绑定)是最常见的防抓包手段之一。与直接使用JustTrustMe等现成工具不同,本文将深入OkHttp、X509TrustManager和CertificatePinne…

2026/7/8 20:30:30
CNN人脸识别模型训练避坑:从64x64图像预处理到Adam优化器调参的3个关键点

CNN人脸识别模型训练避坑:从64x64图像预处理到Adam优化器调参的3个关键点

CNN人脸识别模型训练实战:从64x64图像预处理到Adam优化器调参的深度解析在计算机视觉领域,人脸识别技术已经广泛应用于安防监控、身份认证、智能门禁等场景。然而,当面对小型自建数据集时,如何训练一个高效准确的CNN模型成为许多开…

2026/7/8 20:30:30
iwebsec 靶场代码执行:10关渗透实战与3种通用绕过思路总结

iwebsec 靶场代码执行:10关渗透实战与3种通用绕过思路总结

iwebsec 靶场代码执行:10关渗透实战与3种通用绕过思路总结 在Web安全领域,代码执行漏洞始终是渗透测试中最具破坏力的漏洞类型之一。iwebsec靶场作为国内知名的Web安全实战平台,其代码执行模块设计了10个由浅入深的关卡,全面覆盖了…

2026/7/8 20:25:30

月新闻