前言
vue3 采用的 diff
算法名为快速 diff 算法,整个 diff
算法的过程可以大致分为以下5个阶段。
- 处理前置节点
- 处理后置节点
- 处理仅有新增节点
- 处理仅有删除节点
- 处理其他情况(新增 / 卸载 / 移动)
这里我们先定义新旧两个虚拟节点列表,接下来我们通过这两个列表来模拟下 vue3 的 diff 算法的整个过程。
1. 处理前置节点
从前往后对比新旧两个节点,节点相同则 patch 打补丁更新
这里我们先定义一个 i
变量用于记录前置索引值并初始化 i = 0
,逐个比较它们的节点是否相同。在遍历中可知当 i = 2
的时候新旧节点的值不一样那么我们就停在这里并记录当前 i = 2
。经过这一步我们已经处理完成了前面两个节点。对应的 vue3 源码在这里:
let i = 0
const l2 = c2.length
let e1 = c1.length - 1 // prev ending index
let e2 = l2 - 1 // next ending index
// 1. sync from start
while (i <= e1 && i <= e2) {
const n1 = c1[i]
const n2 = c2[i]
if (isSameVNodeType(n1, n2)) {
patch(n1, n2,container)
} else {
break
}
i++
}
2. 处理后置节点
从后往前对比两个节点,节点相同则 patch 打补丁更新
这里我们定义一个 e1
e2
分别记录新旧节点列表的后置索引值。在遍历中可知当 e1 = 5
e2 = 5
的时候新旧节点的值不一样那么我们就停在这里并记录当前 e1
和 e2
。经过这一步我们已经处理完成了后面一个节点。对应的 vue3 源码在这里:
// 2. sync from end
while (i <= e1 && i <= e2) {
const n1 = c1[e1]
const n2 = c2[e2]
if (isSameVNodeType(n1, n2)) {
patch(n1, n2,container)
} else {
break
}