第 29 题:什么是 Virtual DOM?它的优缺点是什么?Diff 算法是如何工作的?
这是前端框架(Vue/React)必考题,互联网大厂必问。
一、什么是 Virtual DOM?
Virtual DOM(虚拟 DOM)= 用 JS 对象来描述真实 DOM 的结构。
例如真实 DOM:
xml
<div id="app"><span>Hello</span></div>
虚拟 DOM(示意):
css
{
tag: 'div',
props: { id: 'app' },
children: [
{
tag: 'span',
props: null,
children: ['Hello']
}
]
}
它是一颗用 JS 表达的树,不直接操作 DOM,而是操作这棵树。
二、为什么需要 Virtual DOM?它解决了什么问题?
❌ 浏览器直接操作 DOM 的问题:
- DOM 是非常重的对象
- 每次修改都会引发 layout / repaint
- 频繁 DOM 更新会导致性能问题
✔ Virtual DOM 的优势:
- 用 JS 运算代替 DOM 运算(快很多)
- 批量更新 DOM,减少重绘回流
- 跨平台(H5、Native、SSR)
- 提供可控的状态驱动 UI 模型(数据 → UI)
三、Virtual DOM 的缺点
- 首屏速度比直接写原生 DOM 慢
- Diff 也需要计算开销
- 不适合极高性能场景(大量节点/动画)
📌 现阶段:框架(Vue3 / React)都开始弱化 Virtual DOM,比如 Vue3 使用 Proxy + 编译优化,React 也用 Fiber 让 Virtual DOM 更精细。
四、Diff 算法如何工作?(面试必考)
业界通用:
"同层比较 + 关键字优化"
这是一个线性算法 O(n) ,不是树状遍历 O(n³)。
核心规则:
1. 只比较同一层
旧节点:
css
div
├─ p
└─ span
新节点:
css
div
├─ p
└─ a ← 只对比 span 和 a,不跨层
2. 标签不同,直接替换
旧:<p>
新:<div>
→ 整个节点替换
3. 标签相同,比较属性
bash
<div id="a" class="x"></div>
<div id="a" class="y"></div>
只更新 class。
4. 比较 children(重点)
有 3 种情况:
① 全是文本 → 直接替换文本
② 都是列表(v-for)→ 使用 key 优化 Diff
面试官必问:为什么 key 可以提高性能?
因为 key 能让框架识别节点"身份",从而:
- 不会错误复用元素
- 能最小代价移动节点,而不是全部重建
五、举个使用 key 的 Diff 示例(面试最爱)
旧节点:
css
a b c
新节点:
css
c b a
如果没有 key:
→ 可能全部销毁重建(慢)
如果有 key:
→ 只需要移动节点,不破坏 DOM,性能高
六、总结回答(背下来一定能过)
Virtual DOM 是用 JavaScript 对象表示真实 DOM 的树结构,通过 Diff 算法找出最小差异,再一次性更新真实 DOM,从而提升性能。它的优势是减少 DOM 操作、提高渲染效率、跨平台;缺点是首次渲染开销更大,Diff 也有计算成本。Diff 采用同层比较、标签判断、属性比较和基于 key 的最小差异更新策略,使复杂度降低到 O(n)。
如果你愿意,我可以继续 第 30 题:Vue2 和 Vue3 的响应式原理的区别(Proxy vs defineProperty) ?
继续吗?