虚拟DOM
2025-06-05 14:51
真正的理解,往往从质疑“看似理所当然”的东西开始。
当我们开始学习前端框架React
或Vue
时,我们必定会遇到虚拟DOM的概念,但是很多时候只是简单地以提升性能
带过。为了更深入地理解前端框架的核心机制,我们一起来详细了解虚拟DOM。
什么是虚拟DOM
虚拟DOM(Virtual DOM),它是对真实DOM的抽象表示。虚拟 DOM 是使用 JavaScript 对象来描述真实 DOM 的一种方式,它并不直接操作页面,而是作为中间层参与更新过程。该对象包含了真实DOM的结构及其属性,用于对比虚拟DOM和真实DOM的差异,从而进行局部渲染来达到优化性能的目的。 比如一个真实的 DOM 结构是:
HTML<div id="app"> <p class="title">Hello world!</p> </div>
VNode:
JAVASCRIPT{ tag:'div', attrs:{ id:'app' }, children:[ { tag:'p', text:'Hello world!', attrs:{ class:'title', } } ] }
该对象就是我们常说的虚拟 DOM。由于 DOM 是树形结构,使用 JS 对象可以较好地进行描述。
为什么要使用虚拟DOM
当说起虚拟DOM时,大家的第一反应都是提升性能,但是虚拟DOM真的会提升性能吗?
前文我们说了虚拟DOM时对真实DOM的抽象表示,从虚拟 DOM 到真实 DOM,还需要经过 diff 比较、对象创建等多个步骤,按道理来讲直接操作 DOM性能应该更高才对
实际上,虚拟 DOM 并不一定比原生 DOM 操作更快,它的出现并不是为了性能优化
,而是为了让界面更新变得更可控、更易维护、更易跨平台扩展。
当我们单次操作时确实是直接操作DOM更快,因为虚拟DOM要先生成 VDOM、比较、再更新。但是当遇到大量的状态更新时虚拟DOM的优势就体现出来了。
原生 DOM 操作慢的原因不是操作本身慢,而是:
- 每次修改都会触发浏览器的样式计算、布局重排(reflow)、重绘(repaint),代价昂贵;
- 频繁操作会导致 UI 卡顿;虚拟 DOM 就是通过“合并多次更新、集中比较差异”来最小化真实 DOM 操作次数。
虚拟 DOM 带来的优化主要体现在以下几个方面:
- 更高的可维护性(声明式代码
- 更好的开发体验(状态驱动)
- 跨平台能力(可接多种渲染器)
- 更高效的批量 DOM 更新机制(尤其在状态频繁更新时)
举个例子,如果手动操作:
JSif (list[i].status === 'active') { document.querySelector(`#item-${i}`).classList.add('active') } else { document.querySelector(`#item-${i}`).classList.remove('active') }
- 每次都可能重复查找DOM
- 如果有 1000 个项,你得循环判断。
- 开发者很容易“多改”“少改”或忘了同步某些内容。
如果是虚拟DOM:
JSX<li key={i} className={item.status === 'active' ? 'active' : ''}> {item.title} </li>
React
和Vue
会:
- 重新生成虚拟 DOM;
- 对比新旧结构,只更新真正变化的项;
- 最终最小化真实DOM的变更操作。
还有一个核心点在于: 批量异步更新
虚拟DOM框架一般都带有任务调度
:
- 同一帧内多次状态变更,不会多次操作 DOM;
- 而是合并成一次更新;
- 还可以中断、优先级调度(如 React Fiber)。 原生操作中,如果你不手动做防抖/节流,是很难避免性能抖动的。
除了性能优化,虚拟 DOM 的另一个核心价值:解耦 UI 描述和平台渲染
,让跨平台渲染成为可能。
也就是说虚拟DOM + 渲染器 = 多端输出,React的典型代表就是React Native,他的渲染过程就是:
TEXT你写的 JSX ↓ 虚拟 DOM(JS 对象) ↓ 渲染器(Renderer)决定输出: ┌──────────────┬───────────────┐ │ React DOM │ React Native │ │ ➝ HTML │ ➝ 原生组件 │ └──────────────┴───────────────┘
所以虚拟DOM的性能优势不是来自操作快,而是来自:
- 批量更新、差异化更新(diff);
- 避免重复 DOM 访问;
- 自动避免不必要的重排与重绘;
- 统一调度机制;
- 更容易保持 UI 和数据一致性,减少 bug 和维护成本。
最后
虚拟 DOM 并不是一种更“快”的技术方案,相反,从计算量和流程上看,它其实比直接操作真实 DOM 更“慢”——它多了一层抽象、多了一次比较,还需要最终转换为真实 DOM 才能生效。
但它的价值,从来就不在于速度本身,而在于把“更新这件事”变得可控、可预测、可维护。在状态频繁变动、交互复杂的现代 Web 应用中,我们不再依赖开发者一行行手动维护 DOM 的状态,而是交由虚拟 DOM 统一调度、统一比较,最终输出一个尽可能稳定、精准的界面。
它像是一位中间人,虽然动作慢了一点,却用自己的方式,确保每一次变更都恰到好处。对开发者来说,这是一次主动放弃控制权的尝试——把“怎么更新”交给框架,只保留“我想要什么样的状态”这部分描述。
虚拟 DOM 不是更快,但它让我们更自由。 写这篇文章的过程,也像是在学习放慢脚步,好好去理解一个曾被视为“理所当然”的概念。
如果你看到这里,谢谢你花时间阅读这篇小小的开篇文章。希望未来能与你在技术的旅途中有更多交流。