Virtual DOM 是 JavaScript 对真实 DOM 的轻量级抽象,本质是用普通对象描述 DOM 结构的树形数据结构;它不直接操作浏览器 API,仅作为内存中的“快照”,支持序列化、比较与批量更新,将 DOM 操作从命令式转为声明式。

Virtual DOM 是什么?它不是浏览器原生概念
Virtual DOM 是 JavaScript 对真实 DOM 的轻量级抽象,本质是一个用普通对象(plain object)描述 DOM 结构的树形数据结构。它不直接操作浏览器 API,也不挂载到页面上,只是内存中的“快照”。比如 这个对象可序列化、可比较、可批量更新——关键在于它把 DOM 操作从“命令式”变成了“声明式”的中间表示。 浏览器中每次修改 注意:diff 本身有成本,所以 React 18 后默认启用 立即学习“Java免费学习笔记(深入)”; 很多人误以为用了 Virtual DOM 就自动变快,其实它只在特定条件下生效: 当然不是。现代框架已有更多元的优化路径: 真正决定性能的从来不是“有没有 Virtual DOM”,而是“是否避免了不必要的 layout 触发”和“更新是否批量、延迟、可中断”。理解这一点,比记住 diff 算法细节更重要。React.createElement('div', { id: 'app' }, 'Hello') 返回的就不是一个 { type: 'div', props: { id: 'app' }, children: ['Hello'] }
为什么 diff + patch 能减少真实 DOM 操作?
document.body.innerHTML 或调用 element.appendChild() 都会触发样式计算、布局(layout)、绘制(paint),开销大。Virtual DOM 的优化逻辑分两步:
diff(通常是深度优先、同层比对),只找出真正变化的节点路径,跳过未改动的子树patch 指令集(如 INSERT_ELEMENT、UPDATE_TEXT、REMOVE_NODE),再统一应用到真实 DOMconcurrent rendering 把 diff 拆成可中断的小任务;Vue 3 则用更细粒度的响应式依赖追踪,部分场景甚至跳过 diff。Virtual DOM 不等于高性能,滥用反而拖慢渲染
requestAnimationFrame 驱动的位移)——Virtual DOM 的同步更新模型会成为瓶颈,应绕过它直操作 element.style.transform
没有 Virtual DOM 就不能高效更新?
Svelte 在编译期就把响应式逻辑转为直接操作 DOM 的语句,运行时零 Virtual DOMPreact 的 Virtual DOM 实现比 React 更轻,但核心思路一致;Vue 2 用的是带 setter 的观察者模式 + 异步队列更新,不依赖完整 VNode 树 diffdocument.createDocumentFragment() 批量插入、用 el.hidden = true 替代 display: none 减少重排,效果立竿见影











