白狗子的博客

「天上浮云如白衣,斯须改变如苍狗。」——杜甫

Vue-面试-虚拟DOM与Diff

2026年10月16日·Admin·1 次浏览

面试题:虚拟 DOM 是什么?Vue 的 diff 大致怎么做?

常见问法

  • 「虚拟 DOM 一定比直接操作 DOM 快吗?」
  • 「说说 diff 算法」
  • 「为什么要有 VNode?」

虚拟 DOM(VNode)是什么

用 JavaScript 对象描述「真实 DOM 长什么样」:标签名、属性、子节点等。渲染时把 VNode patch 成真实 DOM;更新时用新 VNode 树与旧树对比,算出最小变更集再操作 DOM。

不是为了「更快」,而是为了

  1. 声明式:你只描述状态对应的 UI,框架负责同步 DOM。
  2. 跨平台:同一套 VNode 可对接 DOM、小程序、Canvas 等(思路层面)。
  3. 批量更新:合并同一帧内多次数据变更,减少布局与重绘抖动。

直接精准操作 DOM 在局部、已知结构下可以很快;虚拟 DOM 的价值在于工程化与可维护性,性能是「多数场景下不差 + 可优化」。

Vue diff 思路(与 React 同宗:同层比较)

常见要点:

  1. 同层比较:一般不跨层级移动节点(跨层则销毁再创建),降低复杂度。
  2. 双端比较(经典优化):头头、尾尾、头尾、尾头四种对齐,处理列表尾部增删、反转等常见模式。
  3. key 的作用:列表节点用 stable key 标识「身份」,帮助复用 DOM/组件实例,避免错位更新。

key 错误示例

用 数组下标 作为 key:在列表重排、头部插入时,会导致大量节点身份错乱,引发错误状态复用、动画异常、性能下降。应使用业务唯一 id。

patch 流程(口述版)

patch(oldVNode, newVNode):

  • 若类型不同 → 替换。
  • 若同为元素 → 比 props、比 children(全量 diff 子节点或根据 flag 优化)。
  • 组件节点 → 走组件更新逻辑(props、slots、emit 等)。

Vue3 在编译期可做更多静态标记(PatchFlags、Block Tree),跳过静态节点比对,这是运行时 diff 的重要优化。

© 2025 My Blog. Built with Nuxt.js v4