由于操作DOM是非常浪费性能的,所以在做试图更新之前需要进行新老虚拟节点的对比,找到一个最理想的更新方案。思想就是利用JS的高效弥补操作DOM的低效
在diff算法中最主要的就是两个函数 updateChildren 和 patchVnode,他们两在功能上有着区别(面向的对象不同)但是又有联系。
- patchVnode的作用是以newVnode(源码中命名为vnode)为基准,更新oldVnode,使得两者一致 。(面向两个vnode)
- updateChildren的作用是采用双端算法,以ch为基准更新oldCh(移动,删除,增加),使得ch和oldCh一致。(面向的是两个children数组)
在patchVnode如果两个节点都有子节点那么进入updateChildren的逻辑,在updateChlidren中如果oldVnode和vnode相同(通过sameVnode函数判断)那么进入patchVnode的逻辑。
BTW:这种编码方式在vue中是十分常见的,比如在响应式原理的模块 observer函数 Observer类 defineReactive函数也是相似的逻辑。每个函数或者类面向的对象不同,职责也不同,相互依赖(调用)共同完成某项功能。刚开始看的时候可能会有点晕,但是实际上这样设计才能做到职责的分离。