真实面经题目 · 原创解析
虚拟 DOM 和 diff 算法
这题考察虚拟 DOM 的抽象目的、diff 的启发式假设、key 的节点身份作用和最终 patch 到真实 DOM 的过程。不要把虚拟 DOM 说成一定比直接操作 DOM 快。
真实面经题目 · 原创解析
这题考察虚拟 DOM 的抽象目的、diff 的启发式假设、key 的节点身份作用和最终 patch 到真实 DOM 的过程。不要把虚拟 DOM 说成一定比直接操作 DOM 快。
虚拟 DOM 是用 JS 对象描述 UI 树,包括节点类型、props、children 和 key。状态变化后框架生成新的虚拟树,与旧树做 diff,找出需要新增、删除、移动或更新的部分,再 patch 到真实 DOM。常见 diff 为了把复杂度降下来,会基于不同类型直接替换、同层比较、不跨层全局搜索等假设。key 用来稳定列表节点身份,帮助框架判断复用、移动还是重建。虚拟 DOM 的核心价值是声明式 UI、跨平台抽象和批量更新,不是保证每次都比手写 DOM 更快。
它不是浏览器原生 DOM,而是框架内部的 JS 数据结构。一次渲染结果可以表示为节点类型、属性、事件、子节点和 key 的树。
状态变化后重新执行渲染函数得到新树。框架拿新旧两棵树比较,生成最小程度上足够正确的更新计划,再把更新应用到真实 DOM 或其他渲染目标。
通用树编辑距离复杂度高。前端框架通常采用启发式:不同类型节点直接替换,同类型节点比较属性和子节点,列表在同层根据 key 匹配,不做任意跨层移动搜索。
key 是同层列表节点的稳定身份。稳定 key 能让框架复用正确的 DOM 和组件状态;不稳定 key 会导致错误复用、状态串位或不必要重建。
diff 的结果最终会转成 DOM 操作,例如更新属性、绑定事件、插入节点、删除节点、移动节点。现代框架还会批量调度,避免每次状态变化都同步操作 DOM。
虚拟 DOM 引入了创建对象和 diff 的成本。它的优势在于让开发者用声明式方式表达 UI,并由框架统一优化;对极端性能场景,细粒度响应式或手写优化可能更快。
它需要创建虚拟节点和做 diff,这些都有成本。它减少的是无组织 DOM 操作,并提供统一优化空间,不代表每次都优于精确手写更新。
列表插入、删除、排序时 index 会变化,框架可能错误复用节点和组件状态。稳定业务 id 更能表达节点身份。
任意跨层树比较成本太高。前端 UI 中跨层移动相对少,框架用同层比较换取可接受的性能和实现复杂度。
不完全一样。它们都有虚拟节点和 patch 思路,但调度、响应式触发、block tree、静态提升等优化策略不同。面试答通用原理即可。