diff算法对注释节点直接复用或暴力替换,对文本节点仅整段比对并一次性更新textcontent,不进行字符级diff,因其性能差、无视觉收益且违背最小更新原则。

Diff 算法在处理特殊节点(如注释、文本)时,并不按普通元素节点的逻辑走子节点比对或双端移动,而是采用更直接、轻量的判断与替换策略。
注释节点(EmptyVNode)的处理
注释节点本质是无内容的占位符(isComment = true),不参与 DOM 渲染,也不携带子节点或属性。Diff 过程中:
- 若新旧节点均为注释节点且 key 相同,直接复用,不作任何操作;
- 若 key 不同,或其中一方不是注释节点,则判定为“非同一节点”,直接销毁旧节点、挂载新节点;
- 即使标签名或结构看似相似,只要 isComment 值不一致(比如旧的是注释,新的是文本),就跳过精细化比对,走暴力替换路径。
文本节点(TextVNode)的处理
文本节点只含 text 字段,无子节点、无属性、不可递归 diff。其更新逻辑极简:
- 先通过 sameVnode 判断是否为同一节点:要求 tag === ''(空标签)、isComment === false、key 相同;
- 满足条件后,进入 patchVnode,直接比较 oldVnode.text !== vnode.text;
- 不等则调用 node.textContent = vnode.text 一次性替换,不涉及 DOM 拆分或增量更新;
- 若 text 完全相同,跳过 DOM 操作,连重绘触发都避免。
为什么不对文本做“字符级 diff”?
虽然底层可逐字符比对,但实际框架(Vue/React)均放弃该做法,原因明确:
- 文本节点极少单独频繁变更,多数场景是整段替换(如 {{ msg }});
- DOM 的 textContent 赋值是原子操作,性能远优于手动拆解、高亮、重建;
- 用户不可见中间状态,整替与差替在视觉和语义上无差别;
- 引入字符 diff 会显著增加 patchVnode 复杂度,违背“最小更新”初衷。
组件/克隆节点中的特殊节点
当特殊节点嵌套在 ComponentVNode 或 CloneVnode 中时,diff 仍保持层级隔离:
- 父组件 vnode 的比对结果决定是否复用整个组件实例;
- 若组件被复用,其内部的文本/注释子节点会再次进入独立 patch 流程;
- CloneVNode 仅多一个 isCloned = true 标识,不影响文本或注释的比对逻辑,仅用于优化某些生命周期钩子行为。











