Vue-面试-虚拟DOM与Diff
2026年10月16日·Admin·1 次浏览
面试题:虚拟 DOM 是什么?Vue 的 diff 大致怎么做?
常见问法
- 「虚拟 DOM 一定比直接操作 DOM 快吗?」
- 「说说 diff 算法」
- 「为什么要有 VNode?」
虚拟 DOM(VNode)是什么
用 JavaScript 对象描述「真实 DOM 长什么样」:标签名、属性、子节点等。渲染时把 VNode patch 成真实 DOM;更新时用新 VNode 树与旧树对比,算出最小变更集再操作 DOM。
不是为了「更快」,而是为了
- 声明式:你只描述状态对应的 UI,框架负责同步 DOM。
- 跨平台:同一套 VNode 可对接 DOM、小程序、Canvas 等(思路层面)。
- 批量更新:合并同一帧内多次数据变更,减少布局与重绘抖动。
直接精准操作 DOM 在局部、已知结构下可以很快;虚拟 DOM 的价值在于工程化与可维护性,性能是「多数场景下不差 + 可优化」。
Vue diff 思路(与 React 同宗:同层比较)
常见要点:
- 同层比较:一般不跨层级移动节点(跨层则销毁再创建),降低复杂度。
- 双端比较(经典优化):头头、尾尾、头尾、尾头四种对齐,处理列表尾部增删、反转等常见模式。
- key 的作用:列表节点用 stable key 标识「身份」,帮助复用 DOM/组件实例,避免错位更新。
key 错误示例
用 数组下标 作为 key:在列表重排、头部插入时,会导致大量节点身份错乱,引发错误状态复用、动画异常、性能下降。应使用业务唯一 id。
patch 流程(口述版)
patch(oldVNode, newVNode):
- 若类型不同 → 替换。
- 若同为元素 → 比 props、比 children(全量 diff 子节点或根据 flag 优化)。
- 组件节点 → 走组件更新逻辑(props、slots、emit 等)。
Vue3 在编译期可做更多静态标记(PatchFlags、Block Tree),跳过静态节点比对,这是运行时 diff 的重要优化。