虚拟 dom 的 diff 策略本身不直接支持跨平台,而是通过平台无关的 vnode 比较输出标准化变更指令,由各平台 renderer 分别实现 patch;diff 仅计算“哪里变了”,不涉及平台特有 api 或副作用。

虚拟 DOM 的 diff 策略本身不直接“支持”跨平台,而是为跨平台提供了可复用、平台无关的变更计算能力——它把“哪里变了”这件事剥离出来,交给统一逻辑处理;至于“怎么变”,则完全由各平台渲染器决定。
Diff 算法只管结构差异,不管平台语义
Vue 和 React 的 diff 都遵循同层比较、组件类型优先、key 驱动列表更新等策略。这些策略操作的对象是 VNode(纯 JS 对象),不涉及 DOM API、Canvas 方法或 Native 控件。比如:
- 当一个
v-if切换导致节点增删,diff 仅标记“该位置应无节点”或“需插入新 VNode”; - 当
style属性变化,diff 只记录oldProps.style !== newProps.style,不关心是调用el.style.color = 'red'还是ctx.fillStyle = 'red'; - 列表重排时,key 相同的 VNode 被复用,diff 不生成新节点对象,只调整顺序信息——Canvas 渲染器据此移动绘制区域,Web 渲染器据此调用
insertBefore。
跨平台依赖的是“diff 后的 patch 分发机制”
diff 输出的是一组标准化的变更指令(如:INSERT、UPDATE_PROPS、MOVE、REMOVE),而真正实现这些指令的,是不同平台的 renderer:
- Web renderer 把
INSERT映射为document.createElement+appendChild; - Canvas renderer 把
INSERT映射为创建图形状态对象 + 记录绘制坐标与样式; - 小程序 renderer 把
UPDATE_PROPS转为setData中的字段更新; - 所有 renderer 共享同一套 diff 输出结果,只是 patch 实现完全不同。
关键设计让 diff 天然适配多端
虚拟 DOM 的轻量结构和平台中立性,使 diff 过程天然可移植:
- VNode 不含平台专属字段(如
el、ctx、nativeView),只有 type/props/children/key 等通用描述; - diff 过程不触发任何副作用,全程在内存中比对,不访问浏览器 API、不调用绘图上下文;
- Vue3 的
renderer.ts明确将 patch 行为抽象为可注入函数,diff 结果作为输入,交由平台 renderer 解释执行。
不是 diff 支持跨平台,而是 diff 让跨平台更可控
没有 diff,每个平台都要自己实现“状态到视图”的映射逻辑,容易重复、难维护、更新不一致;有了 diff,所有平台共享同一套变更识别规则,只要 renderer 正确实现 patch 接口,就能保证:同一份组件代码、同一组数据变化,在 Web 上删节点、在 Canvas 上清区域、在小程序里隐藏 view——行为语义一致,实现路径分离。










