React、Vue 基于 VDOM 的渲染流程存在三层无法根治的固有损耗,即便通过编译时优化缓解,也不能从根源消除开销。
完整VDOM树创建与内存开销
每次组件重渲染,框架需要完整生成新 VDOM 对象树:包含标签、属性、子节点、文本等海量 JS 对象,长列表场景下单次渲染会创建数万临时对象,持续触发 V8 GC,造成周期性主线程卡顿。Vue 3 通过静态提升跳过静态节点创建、React 依靠 memo/useMemo 减少重渲染,但动态数据驱动的动态节点仍会完整生成 VDOM,内存开销无法根除。
Diff对比的全树遍历损耗
状态变更后,框架必须递归遍历新旧两棵 VDOM 树进行 Diff 匹配:
- 节点层级对比key 匹配、属性全量对比;
- 列表场景需要链表排序、移位、删除、新增运算。
即便页面仅一处文本变更,组件树所有祖先组件依然会执行重渲染与 Diff 遍历,只是最终无 DOM 操作,产生大量无效 CPU 运算。
批量更新调度的额外缓冲层
为减少频繁 DOM 操作,VDOM 框架引入异步更新队列:状态变更先存入队列,微任务批量执行 Diff 与 DOM 更新,这套调度机制增加一层事件循环开销;同时批量更新会带来"状态不同步"、竞态、多次渲染等衍生问题,开发者需要额外使用 useTransition、watch 等 API 兜底。
组件粒度耦合问题
VDOM 以组件为最小更新单元,而非 DOM 节点:一个组件内任意响应式变量变更,整个组件所有 DOM 都要经过重渲染与 Diff,无法做到"单个文本、单个属性独立更新",组件粒度拆分过细又会增加组件实例、上下文嵌套开销,陷入粒度拆分两难。