双端比较是Vue2列表更新的核心Diff策略,通过oldStart/oldEnd/newStart/newEnd四个指针,按头头、尾尾、头尾、尾头顺序匹配,匹配成功则移动指针,全不中时回退key映射查找,兼顾效率与兜底。

“双端比较”是 Vue2 中用于列表更新的核心 Diff 策略,本质是一种在新旧子节点数组两端同时推进、分四路尝试匹配的高效比对方法。它不追求穷举所有可能,而是基于现实场景中节点移动常发生在首尾的直觉,用四个指针快速收敛差异,把时间复杂度控制在 O(n)。
双端比较怎么运作?
算法维护四个索引指针:
- oldStartIdx / oldEndIdx:指向旧子节点数组的开头和结尾
- newStartIdx / newEndIdx:指向新子节点数组的开头和结尾
每轮循环按固定顺序尝试四种匹配:
- 旧头 vs 新头(oldStart ↔ newStart)→ 位置未变,直接 patch
- 旧尾 vs 新尾(oldEnd ↔ newEnd)→ 尾部稳定,原地更新
- 旧头 vs 新尾(oldStart ↔ newEnd)→ 节点从尾移到头,执行 DOM 移动
- 旧尾 vs 新头(oldEnd ↔ newStart)→ 节点从头移到尾,同样移动
一旦某路匹配成功,对应指针前移或后缩;若四路全不中,则退回到 key 映射表查找——这是兜底逻辑,确保任意乱序都能处理。
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
立即学习“前端免费学习笔记(深入)”;
为什么 Vue2 选它?核心优势在哪?
相比朴素逐项比对,双端比较显著减少 DOM 操作次数:
- 面对
[A, B, C, D]→[D, A, B, C]这类常见位移,只需移动 D 一次,而非销毁重建全部四项 - 前置/后置连续相同节点能被快速跳过,无需进入复杂逻辑
- 实现简洁,运行时开销小,适合当时主流设备性能
它的局限性也很明确
双端策略依赖“大部分变化集中在两端”的经验假设,在真实业务中并不总成立:
- 中间插入或删除节点时,容易触发多次 key 查找,退化为 O(n²) 行为
- 无法识别“部分有序”结构,比如
[A, C, E, B, D]中隐含的递增序列[A, B, C, D, E],它仍会频繁移动 - 没有预处理机制,每次 diff 都要从头扫描,静态内容重复比对
- key 缺失或重复时,行为不可控,容易导致状态错乱或内存泄漏
它为 Vue3 埋下了演进伏笔
Vue3 的快速 Diff 并非推翻双端思想,而是补足其短板:加入前后缀预处理跳过稳定段,再对剩余乱序段用最长递增子序列(LIS)锁定不动节点——这本质上是把“双端试探”升级为“先稳后优”。双端比较的价值,正在于它用极简模型验证了 key + 同层 + 移动优先这一整套思路的可行性。

















