React 的虚拟 DOM 是什么?它解决了什么问题?
虚拟 DOM 是一个 JavaScript 对象树,是真实 DOM 的轻量级副本。
工作流程
状态变化 → 生成新虚拟DOM → 与旧虚拟DOM对比(Diff) → 最小化更新真实DOM为什么需要虚拟 DOM
- 减少直接 DOM 操作:DOM 操作昂贵(涉及重排重绘),虚拟 DOM 在内存中操作 JS 对象更快
- 批量更新:状态变化先在虚拟 DOM 中合并,最后一次性更新真实 DOM
- 跨平台:虚拟 DOM 是 JS 对象,可以渲染到不同平台(浏览器、Native、SSR)
简化实现
// 虚拟 DOM 节点
const vdom = {
type: 'div',
props: { className: 'container' },
children: [
{ type: 'h1', props: {}, children: 'Hello' },
{ type: 'p', props: {}, children: 'World' }
]
}
// 渲染为真实 DOM
function render(vdom) {
if (typeof vdom === 'string') return document.createTextNode(vdom)
const el = document.createElement(vdom.type)
Object.entries(vdom.props).forEach(([k, v]) => el.setAttribute(k, v))
vdom.children.forEach(child => el.appendChild(render(child)))
return el
}Diff 算法
React 的 Diff 算法有三个假设:
- 不同类型的元素产生不同的树(div → span 会销毁重建)
- 通过 key 标识同一层级的子元素
- 只比较同一层级(不跨层级比较)
虚拟 DOM 的代价
- 首次渲染需要构建虚拟 DOM 树,有额外开销
- 不是所有场景都比直接 DOM 操作快(简单更新场景不如原生)
- Svelte 等框架编译时优化,跳过虚拟 DOM
面试要点
- 虚拟 DOM 不是为了"比直接操作 DOM 快",而是为了声明式编程和跨平台
- 性能优势来自于批量更新和最小化 DOM 操作