虚拟DOM是用JS对象模拟DOM的机制,核心在于减少无效DOM操作;它通过差异计算和批量更新提升性能,依赖key优化列表渲染,并支持跨平台与声明式开发。

虚拟DOM是用普通JavaScript对象模拟真实DOM结构的一套机制,它本身不直接操作浏览器,而是作为中间层,在内存中描述UI状态。它提升性能的关键不在“快”,而在于“少”——大幅减少对真实DOM的无效或重复操作。
虚拟DOM本质上是个JS对象树
每个虚拟DOM节点就是一个轻量级对象,通常包含三个核心字段:tag(标签名)、props(属性对象,如id、class、style等)、children(子节点数组,可以是字符串、其他vnode或空)。比如一个
Hi
{ tag: 'div', props: { id: 'app' }, children: [ { tag: 'p', props: {}, children: ['Hi'] } ] }
这个结构完全在JS引擎里运行,创建、比对、丢弃都极快,不触发浏览器渲染流水线。
立即学习“Java免费学习笔记(深入)”;
它靠“差异计算+批量更新”省掉大量DOM操作
真实DOM操作昂贵,因为每次增删改都可能触发重排(reflow)和重绘(repaint),浏览器要重新计算布局、样式、绘制图层。虚拟DOM绕开了这个问题:
- 状态变时,框架生成一棵新虚拟DOM树,不碰真实DOM
- 用Diff算法对比新旧两棵树,只找出真正变化的节点路径(比如某个
- 的文本变了,或列表末尾新增一项)
- 把所有变更打包成“补丁”(patch),一次性应用到真实DOM上
- 没变的部分完全跳过,连getter都不触发
这就避免了“改一个字就重刷整块区域”或“连续点按钮导致DOM反复增删”的低效行为。
key属性让列表更新更聪明
渲染动态列表时,光靠顺序对比容易误判。比如把['A','B','C']变成['B','C','D'],没有key的话,框架可能认为A被替换成B、B→C、C→D,结果执行三次替换;加上唯一key后,它能识别出B和C是原地复用,只删除A、新增D。
所以写列表时必须给每项设稳定key(如id),否则Diff会退化为低效模式,性能反而不如手动操作。
它还带来跨平台和开发体验优势
虚拟DOM是纯JS数据结构,不依赖浏览器环境。同一套vnode逻辑,可渲染到Web DOM、iOS原生视图、小程序容器甚至终端字符界面。这对React Native、Taro、uni-app等方案至关重要。
对开发者来说,不用再写document.getElementById、innerHTML拼接或jQuery链式调用,专注描述“想要什么状态”,框架自动搞定“怎么变过去”。代码更声明式、更易测、协作成本更低。
基本上就这些。不复杂但容易忽略:虚拟DOM不是银弹,它优化的是“频繁小更新”的场景;真有极致性能需求(如编辑器、实时图表),还是得绕过它直接操作DOM。











