【前端每天一题】🔥 第 25 题:什么是 Virtual DOM?它的优缺点是什么?Diff 算法是如何工作的?


第 29 题:什么是 Virtual DOM?它的优缺点是什么?Diff 算法是如何工作的?

这是前端框架(Vue/React)必考题,互联网大厂必问。


一、什么是 Virtual DOM?

Virtual DOM(虚拟 DOM)= 用 JS 对象来描述真实 DOM 的结构。

例如真实 DOM:

xml 复制代码
<div id="app"><span>Hello</span></div>

虚拟 DOM(示意):

css 复制代码
{
  tag: 'div',
  props: { id: 'app' },
  children: [
    {
      tag: 'span',
      props: null,
      children: ['Hello']
    }
  ]
}

它是一颗用 JS 表达的树,不直接操作 DOM,而是操作这棵树。


二、为什么需要 Virtual DOM?它解决了什么问题?

❌ 浏览器直接操作 DOM 的问题:

  • DOM 是非常重的对象
  • 每次修改都会引发 layout / repaint
  • 频繁 DOM 更新会导致性能问题

✔ Virtual DOM 的优势:

  1. 用 JS 运算代替 DOM 运算(快很多)
  2. 批量更新 DOM,减少重绘回流
  3. 跨平台(H5、Native、SSR)
  4. 提供可控的状态驱动 UI 模型(数据 → UI)

三、Virtual DOM 的缺点

  1. 首屏速度比直接写原生 DOM 慢
  2. Diff 也需要计算开销
  3. 不适合极高性能场景(大量节点/动画)

📌 现阶段:框架(Vue3 / React)都开始弱化 Virtual DOM,比如 Vue3 使用 Proxy + 编译优化,React 也用 Fiber 让 Virtual DOM 更精细。


四、Diff 算法如何工作?(面试必考)

业界通用:

"同层比较 + 关键字优化"

这是一个线性算法 O(n) ,不是树状遍历 O(n³)。


核心规则:

1. 只比较同一层

旧节点:

css 复制代码
div
 ├─ p
 └─ span

新节点:

css 复制代码
div
 ├─ p
 └─ a   ← 只对比 span 和 a,不跨层

2. 标签不同,直接替换

旧:<p>

新:<div>

整个节点替换


3. 标签相同,比较属性

bash 复制代码
<div id="a" class="x"></div>
<div id="a" class="y"></div>

只更新 class。


4. 比较 children(重点)

有 3 种情况:

① 全是文本 → 直接替换文本

② 都是列表(v-for)→ 使用 key 优化 Diff

面试官必问:为什么 key 可以提高性能?

因为 key 能让框架识别节点"身份",从而:

  • 不会错误复用元素
  • 能最小代价移动节点,而不是全部重建

五、举个使用 key 的 Diff 示例(面试最爱)

旧节点:

css 复制代码
a b c

新节点:

css 复制代码
c b a

如果没有 key:

→ 可能全部销毁重建(慢)

如果有 key:

→ 只需要移动节点,不破坏 DOM,性能高


六、总结回答(背下来一定能过)

Virtual DOM 是用 JavaScript 对象表示真实 DOM 的树结构,通过 Diff 算法找出最小差异,再一次性更新真实 DOM,从而提升性能。它的优势是减少 DOM 操作、提高渲染效率、跨平台;缺点是首次渲染开销更大,Diff 也有计算成本。Diff 采用同层比较、标签判断、属性比较和基于 key 的最小差异更新策略,使复杂度降低到 O(n)。


如果你愿意,我可以继续 第 30 题:Vue2 和 Vue3 的响应式原理的区别(Proxy vs defineProperty)

继续吗?

相关推荐
Highcharts.js1 小时前
如何下载使用Highcharts Grid 开发web可编辑表格
前端·人工智能·grid 表格·web 表格·在线编辑表格·highcharts表格安装·表格开发工具
用户62960593247051 小时前
从“浏览器根本区分不了”到真正实现:刷新不退出,关闭标签页自动退出,前端判断浏览器关闭和刷新
前端
qetfw1 小时前
MWU:Vue 3 + FastAPI 的 MaaFramework 跨平台 WebUI 源码
前端·vue.js·python·fastapi·开源项目·效率工具
mfxcyh1 小时前
Vue3+Ant Design Vue 实现手动异步文件上传(含大小校验、弹窗上传)
前端·javascript·vue.js
wordbaby1 小时前
Web端热敏标签打印完整解决方案(QZ Tray + 译维A42)
前端
swipe2 小时前
03|Axios 请求进了后端之后:Controller、Request、Response 是怎么接住它的?
前端·后端·全栈
meilindehuzi_a2 小时前
Vue3进阶基础:指令修饰符、v-model表单绑定、动态样式、计算属性与侦听器实战
前端·javascript·vue.js
csdn2015_2 小时前
vue 前端运行命令
前端·javascript·vue.js
swipe2 小时前
02|从 `pnpm dev` 到 Spring Boot 启动:后端服务到底怎么跑起来?
前端·后端·全栈
swipe2 小时前
01|前端人第一次打开 Spring Boot 项目,应该先看哪里?
前端·后端·全栈