Diff算法

·虚拟DOM中的Diff算法

·查找两颗树每一个节点的差异

Snabbdom根据DOM的特点对传统的diff算法做了优化

·DOM操作时候很少会跨级别操作节点

·只比较同级别的节点

updateChildren整体分析 - 图1

执行过程

·在对开始和结束节点比较的时候,总共有四种情

·oldStartVnode/newStartVnode(旧开始节点/新开始节点)

·oldEndVnode/newEndVnode(旧结束节点/新结束节点)

·oldstartnode/newEndVnode(旧开始节点/新结束节点)

·oldEndVnode/newStartVnode(旧结束节点/新开始节点)

updateChildren整体分析 - 图2

新旧开始节点

·如果新旧旧开始节点是sameVnode(key和sel相同)

·调用patchVnodeO对比和更新节点

·把旧开始和新开始索引往后移动oldStartldx+/newStartldx+

updateChildren整体分析 - 图3

旧开始节点/新结束节点

调用patchVnode()对比和更新节点

把oldStartVnode对应的DOM元素,移动到右边,更新索引

updateChildren整体分析 - 图4

旧结束节点/新开始节点

调用patchVnodeO对比和更新节点

把oldEndVnode对应的DOM元素,移动到左边,更新索引

updateChildren整体分析 - 图5

非上述四种情况

updateChildren整体分析 - 图6

·遍历新节点,使用newStartNode的key在老节点数组中找相同节点

·如果没有找到,说明newStartNode是新节点

·创建新节点对应的D0M元素,插入到D0M树中

·如果找到了

·判断新节点和找到的老节点的sel选择器是否相同

·如果不相同,说明节点被修改了,重新创建对应的DOM元素,插入到DOM树中

如果相同,把elmToMove对应的D0M元素,移动到左边

循环结束

·当老节点的所有子节点先遍历完(oldstartldx>oldEndldx),循环结束

·新节点的所有子节点先遍历完(newstartldx>newEndldx),循环结束

oldStartldx > oldEndldx

·如果老节点的数组先遍历完(oldStartldx>oldEndldx)

·说明新节点有剩余,把剩余节点批量插入到右边

updateChildren整体分析 - 图7

newStartldx >newEndldx

·如果新节点的数组先遍历完(newStartldx>newEndldx)

·说明老节点有剩余,把利余节点批量删除

updateChildren整体分析 - 图8