《Vue.js设计与实现》 第九章 简单 Diff 算法
当新旧 vnode 的子节点都是一组节点时,为了以最小的性能开销完成更新操作,需要比较两组子节点,用于比较的算法就叫作 Diff 算法。
9.1 减少 DOM 操作的性能开销
场景: 标签相同,子节点是文本节点,文本内容不同时
虚拟节点:
01 // 旧 vnode
02 const oldVNode = {
03 type: 'div',
04 children: [
05 { type: 'p', children: '1' },
06 { type: 'p', children: '2' },
07 { type: 'p', children: '3' }
08 ]
09 }
10
11 // 新 vnode
12 const newVNode = {
13 type: 'div',
14 children: [
15 { type: 'p', children: '4' },
16 { type: 'p', children: '5' },
17 { type: 'p', children: '6' }
18 ]
19 }
算法
描述:
遍历旧的 children,调用 patch 函数逐个更新子节点
代码:
01 function patchChildren(n1, n2, container) {
02 if (typeof n2.children === 'string') {
03 // 省略部分代码
04 } else if (Array.isArray(n2.children)) {
05 // 重新实现两组子节点的更新方式
06 // 新旧 children
07 const oldChildren = n1.children
08 const newChildren = n2.children
09 // 遍历旧的 children
10 for (let i = 0; i < oldChildren.length; i++) {
11 // 调用 patch 函数逐个更新子节点
12 patch(oldChildren[i], newChildren[i])
13 }
14 } else {
15 // 省略部分代码
16 }
17 }