Vue3 Diff算法核心优化实现
// Vue3 Diff算法核心优化实现function patchKeyedChildren(c1, c2, container) { let i = 0; const l1 = c1.length; const l2 = c2.length; let e1 = l1 - 1; let e2 = l2 - 1; // 1. 同步前置节点 while (i <= e1 && i <= e2) { const n1 = c1[i]; const n2 = c2[i]; if (isSameVNode(n1, n2)) { patch(n1, n2, container); } else { break; } i++; } // 2. 同步后置节点 while (i <= e1 && i <= e2) { const n1 = c1[e1]; const n2 = c2[e2]; if (isSameVNode(n1, n2)) { patch(n1, n2, container); } else { break; } e1--; e2--; } // 3. 处理新增/删除节点 if (i > e1) { // 新增节点 if (i <= e2) { const nextPos = e2 + 1; const anchor = nextPos < l2 ? c2[nextPos].el : null; while (i <= e2) { patch(null, c2[i], container, anchor); i++; } } } else if (i > e2) { // 删除节点 while (i <= e1) { unmount(c1[i]); i++; } } else { // 4. 处理中间乱序节点 const s1 = i; const s2 = i; const keyToNewIndexMap = new Map(); for (let j = s2; j <= e2; j++) { const nextChild = c2[j]; keyToNewIndexMap.set(nextChild.key, j); } const toBePatched = e2 - s2 + 1; const newIndexToOldIndexMap = new Array(toBePatched).fill(0); for (let j = s1; j <= e1; j++) { const prevChild = c1[j]; const newIndex = keyToNewIndexMap.get(prevChild.key); if (newIndex === undefined) { unmount(prevChild); } else { newIndexToOldIndexMap[newIndex - s2] = j + 1; patch(prevChild, c2[newIndex], container); } } const increasingNewIndexSequence = getSequence(newIndexToOldIndexMap); let j = increasingNewIndexSequence.length - 1; for (let i = toBePatched - 1; i >= 0; i--) { const nextIndex = s2 + i; const nextChild = c2[nextIndex]; const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : null; if (newIndexToOldIndexMap[i] === 0) { patch(null, nextChild, container, anchor); } else if (i !== increasingNewIndexSequence[j]) { insert(nextChild.el, container, anchor); } else { j--; } } }}function getSequence(arr) { const p = arr.slice(); const result = [0]; let start, end, middle; for (let i = 0; i < arr.length; i++) { const arrI = arr[i]; if (arrI !== 0) { let resultLastIndex = result[result.length - 1]; if (arr[resultLastIndex] < arrI) { p[i] = resultLastIndex; result.push(i); continue; } start = 0; end = result.length - 1; while (start < end) { middle = ((start + end) / 2) | 0; if (arr[result[middle]] < arrI) { start = middle + 1; } else { end = middle; } } if (arr[result[start]] > arrI) { if (start > 0) { p[i] = result[start - 1]; } result[start] = i; } } } let i = result.length - 1; let last = result[i]; while (i >= 0) { result[i] = last; last = p[last]; i--; } return result;}代码说明:
实现了Vue3核心Diff算法流程:同步前置/后置节点、处理新增/删除节点、中间乱序节点的最长递增子序列优化
通过静态标记和patchFlag优化:跳过静态节点、仅对比动态变化部分
支持Fragment(多根节点)和事件缓存:减少DOM层级、复用事件函数
通过getSequence函数实现最长递增子序列算法:O(nlogn)时间复杂度
包含isSameVNode、patch、unmount、insert等辅助函数(未实现)
