Vue 3 的 Diff 算法怎么工作?最长递增子序列有什么用?
下面是一段教学用的模拟面试。
🧑💻 面试官:Vue 3 更新列表时,Diff 是怎么做的?
🙋♂️ 我:比较新旧节点,通过 key 找到相同节点,再更新 DOM。
🧑💻 面试官:旧顺序是 A、B、C、D、E,新顺序是 A、C、D、B、E。每个节点都找到了,为什么还需要最长递增子序列?
🙋♂️ 我:为了减少节点移动。
🧑💻 面试官:具体留下哪些节点、移动哪个?最长递增子序列是在给 key 排序吗?
答好这道题,要分开「身份相同」和「位置合适」。key 帮你复用节点,最长递增子序列帮你少移动已经复用的 DOM。
面试速答(60 秒版)
Vue 3 处理带 key 的子节点时,会先比较两端可以直接匹配的部分,再处理中间发生变化的节点。
处理中间部分时,它通过 key 查找对应节点,更新可以复用的节点,删除不存在的旧节点,并识别需要新建的节点。对于可以复用、但顺序发生变化的节点,还需要安排 DOM 移动。
最长递增子序列就是在这一步发挥作用:把新节点顺序对应的旧位置记下来,找出其中相对顺序已经正确的一组节点,让它们保持不动,其余节点再移动。
因此,它不是把 key 排序,也不是让所有节点不移动。实际写列表时,要使用能稳定表示数据身份的 key;如果列表会增删、重排,就不能随意拿数组下标当身份。

知识点详解:从一次列表重排理解 Vue 3 的 Diff
本文沿着 Vue core v3.5.22 的 renderer 源码 中带 key 子节点的更新分支讲解。Vue 3 还有编译优化、静态提升等机制,这里不把它们都塞进同一道题。
比较之前,先明确“相同节点”是什么意思
咱们假设页面有五条任务,key 分别是 A、B、C、D、E。旧顺序是 A、B、C、D、E,调整后变成 A、C、D、B、E。
任务 B 只是换了位置,它还是原来的任务。如果类型与 key 都能对应,Vue 就有机会复用原来的节点,再更新属性和内容,而不是把 B 销毁以后重新创建。
因此,Diff 不只是比较字符串。它需要确认节点身份,再安排对应的更新。假如 key 相同但组件类型变了,也不能据此认为原组件必然复用。
先跳过两端,再处理中间
这组数据的开头 A 没变,末尾 E 也没变。Vue 3 会先同步这些可以直接对应的头部、尾部节点。
剩下的变化就集中在旧的 B、C、D 和新的 C、D、B。
如果比较到后来,旧节点先用完了,剩余新节点就是插入;新节点先用完了,剩余旧节点就是删除。只有两边中间都还存在未处理节点,才需要继续建立新节点 key 到位置的映射。
接着遍历旧中间节点:旧 B 可以找到新 B,旧 C 可以找到新 C,旧 D 可以找到新 D,于是都能更新并复用。找不到对应项的旧节点才会被卸载。
同时还会记录:按照新顺序排列的这些节点,原来分别位于什么位置。 这份记录才是后面判断移动的依据。

为什么 2、3、1 里要留下 2、3?
为了方便推演,给旧列表的位置从 0 编号:A 是 0,B 是 1,C 是 2,D 是 3,E 是 4。
新中间顺序是 C、D、B,所以对应的旧位置就是 2、3、1。源码内部记录会使用位置加一等实现细节,咱们这里保留原位置数字,方便理解。
其中 2、3 是递增的,表示 C 原来就在 D 前面,现在也仍然在 D 前面。它们之间的相对顺序没有问题,可以留下。
B 原来在 C、D 前面,现在需要放到 D 后面。因此,只移动 B,就能得到 A、C、D、B、E。不需要再把 C、D 各移动一次。
最长递增子序列找的是这样的“相对顺序已正确的最大一组”,不是连续片段,也不是 key 的大小顺序。源码再从后往前处理,用后面的节点作为插入位置参考,完成新增和必要移动。
如果没有发生顺序变化,就不必为了形式计算一遍 LIS。这个优化针对的是需要移动的中间部分,不能背成“所有 Diff 都必然执行 LIS”。

面试官继续追问
为什么数组下标当 key 容易出问题?
假设在列表开头插入一条任务,原来下标为 0 的任务变成了下标 1。下标对应的身份变了,组件可能按位置复用给另一条数据,输入状态等就可能错位。稳定 ID 才更符合这组数据的身份。
key 能保证 DOM 完全不用更新吗?
不能。key 只是身份线索,节点内容、属性、子节点仍可能需要更新。稳定身份也不代表位置没有变化。
Vue 3 用的是 Vue 2 那套双端比较吗?
不能直接套旧版口诀。本题讲的是 Vue 3 的头尾同步、中间映射和必要时 LIS 的处理路径。面试时先说明版本和更新场景,别把两份实现混在一起。
面试速记卡
- 节点身份:类型与 key 是否能对应,不是只看内容相似。
- 处理顺序:先同步头尾,再处理剩余中间部分。
- key 映射:帮助寻找可复用节点,不负责给数据排序。
- LIS:保留相对顺序已正确的一组节点,减少必要移动。
- 列表 key:优先稳定业务 ID,重排列表不要随意使用下标。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →