绪论
首先我们先了解,DOM(Document Object Model,文档对象模型) 是浏览器对 HTML/XML 文档的结构化表示,它将文档解析为一个由节点(Node)和对象组成的树形结构(称为 DOM 树),允许程序(如 JavaScript)动态访问、修改文档的内容、结构和样式。
DOM 的本质是树形结构:
浏览器加载 HTML 后,会将其解析为逻辑上的树状结构,每个 HTML 标签、属性、文本都是一个节点(Node)。具体如下图所示:
DOM 的作用
动态操作页面:
通过 JavaScript 操作 DOM 节点,实现交互效果(如点击按钮修改文字、新增列表项)。
示例代码:
// 获取元素
const title = document.getElementById("title");
// 修改内容
title.textContent = "新标题";
// 添加新节点
const newParagraph = document.createElement("p");
newParagraph.textContent = "新增段落";
document.body.appendChild(newParagraph);
在 Vue 中,虚拟 DOM(Virtual DOM) 是一个核心概念,它是一种用 JavaScript 对象(称为 VNode)模拟真实 DOM 结构的轻量级抽象。其核心作用是优化渲染性能,解决直接操作真实 DOM 带来的效率问题。
一、虚拟 DOM 的工作原理:
-
生成虚拟 DOM:
当组件状态(data
)变化时,Vue 会重新执行render
函数,生成一个新的虚拟 DOM 树(由 VNode 节点组成的树形结构)。 -
Diff 对比:
Vue 会将新旧两棵虚拟 DOM 树进行精细对比(Diff 算法),找出两者之间的最小差异(例如哪些节点需要更新、添加或删除)。 -
局部更新真实 DOM:
仅将差异部分应用到真实 DOM 上(这一过程称为 Patch),而非直接替换整个 DOM 树。
二、为什么需要虚拟 DOM?
-
性能优化:
- 直接操作真实 DOM 成本高昂(浏览器需重排/重绘)。
- 虚拟 DOM 在内存中操作 JavaScript 对象,速度极快。
- 批量更新:多次状态变化可合并为一次 DOM 更新。
-
跨平台能力:
- 虚拟 DOM 是纯 JavaScript 对象,与平台无关。
- 同一套代码可渲染到 Web(浏览器 DOM)、移动端(Weex/React Native)或服务端(SSR)。
-
声明式编程:
- 开发者只需关注数据逻辑(
data
),无需手动操作 DOM(如document.getElementById()
)。
- 开发者只需关注数据逻辑(
三、虚拟 DOM 的简单示例
假设一个模板:
<div id="app">
<p class="text">{{ message }}</p>
</div>
对应的虚拟 DOM 对象(VNode)类似:
{
tag: 'div',
attrs: { id: 'app' },
children: [
{
tag: 'p',
attrs: { class: 'text' },
children: [ message ] // 动态数据
}
]
}
四、虚拟 DOM 的局限性
- 内存占用:需额外存储虚拟 DOM 树。
- 不适用简单场景:对静态页面或极少更新的组件,虚拟 DOM 反而增加开销。
- 无法完全替代手动优化:极端性能场景仍需手动操作 DOM(如
v-once
或直接使用ref
)。
Vue 中的关键实现:
render()
函数:将模板编译为虚拟 DOM。- Diff 算法:
- 同级比较(避免跨层级对比)
- 通过
key
属性复用节点(如v-for
循环中)
- Patch 机制:高效更新真实 DOM。
五、总结
特点 | 真实 DOM | 虚拟 DOM |
---|---|---|
操作成本 | 高(触发重排/重绘) | 低(内存操作 JS 对象) |
更新方式 | 直接修改 | Diff + 局部更新 |
跨平台 | 仅浏览器 | 支持 Web/移动端/服务端 |
适用场景 | 简单静态页面 | 动态复杂应用 |
虚拟 DOM 是 Vue 响应式系统的基石,它通过智能的差异对比,在数据变化时以最小代价更新视图,大幅提升复杂应用的性能表现。