react diff算法实现我们了解了,我们继续对比学习以下vue的算法流程是怎样的

VUE算法时间复杂度

同样是将时间复杂度降低到了O(n)

Vue对diff算法的改进

1、和react的策略如出一辙,同样的三条策略
2、唯一不同点在于element diff的纬度上vue有了自己的想法

Vue对element diff做的优化

深度解析dom diff算法(三)

在vue内部遍历新旧树同一层级节点时,对于旧树和新树分别有一个头尾指针(共四个指针,分别是oldStart,oldEnd,newStart,newEnd),利用这四个指针按一定规则进行比较,规则如下:
1、先比较头头/尾尾节点
2、再比较头尾/尾头节点
3、处理新增节点
4、处理更新节点
也就是上图所示,看着比较清楚,以上所有情况处理完成后,最后只剩下被删除掉的节点,那么去遍历旧树,将节点删除
注意,当处理某一对节点时,一定严格按照图中所示的顺序去处理,当某一种情况不存在时再去考虑下一种情况,以此类推

下面我们拿一个demo来举例

深度解析dom diff算法(三)
一、开始遍历前指针情况如上,old代表老的节点,new代表新的节点,那我们开始按照上面的策略开始

1、比较头头节点,发现旧树头部指针(oldStart)的节点是1,新树头部指针(newStart)的节点也是1,节点没变那么指针直接同步加一,移到了2,6的位置
2、比较尾尾节点,同上情况,那么尾部指针同步加一,到了6,2位置
如下图所示

深度解析dom diff算法(三)

二、继续进行,按照我们的策略顺序,发现属于第二种情况,处理头尾/尾头

1、先比较头尾节点,发现oldStart和newEnd节点相同,那么此时有个规则“头尾情况,oldStart节点插入到oldEnd后”,之后oldStart和newEnd同步加一
深度解析dom diff算法(三)
2、再比较尾头节点,同上节点相同,此时有规则“尾头情况,oldEnd插入到oldStart前”,指针同步加一
深度解析dom diff算法(三)

上面步骤处理完后的情况
深度解析dom diff算法(三)
三、我们继续,重新看回遍历策略,发现目前只有新增节点(节点8)这一情况符合

newStart指针指向新增节点,处理新增节点有规则“新增节点插入到oldStart之前”,处理完newStart指针加一,如下
深度解析dom diff算法(三)深度解析dom diff算法(三)

四、现在重新看回我们的遍历策略,发现又是头头/尾尾的情况

newStat和oldStart指针同步后移,出现了下面的情况
深度解析dom diff算法(三)
这也正是我们遍历结束的情况,分两种:
1、oldStart > oldEnd
2、newStart > newEnd
上面demo属于第二种,遍历结束后同时结束我们的遍历策略循环,回到我们最开始的图片看最后一步,处理删除节点,发现节点5被删除,最终新的节点集合就诞生了。

五、总结

以上就是我们vue的diff算法策略,会发现和react的策略差别还挺大,但这个世界之所以精彩不就是因为多样性,代码也是如此,对于同一个问题十个人可能就有十个思路,但最终解决问题是根本。相信一句话,方法总比困难多,最重要的是在这些方法之中有值得让你学习和借鉴的地方就足够了。

相关文章: