您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

由浅入深读透vue源码:diff算法

时间:2023-01-08 14:11:37  来源:今日头条  作者:闪现基因

导语 | 开发者工作中,研究代码逻辑常需要思考这个问题:数组变更后,具体变更了哪一些元素?变更的位置如何?本文作者陈碧松解析并覆写了针对数组变化的diff算法逻辑。希望本文对你有帮助。

 

diff方法的运行规则和前提方法

为了了解diff方法的运行规则和前提方法,首先我们通过几个图快速区别虚拟node进行深度优先和同级对比。

深度优先:


 

同级对比:


 

如上面图所示,每次vnode都是执行同级对比。(对应dom同一个父元素)

代码逻辑如下图:


 

第二,简单判断:`sameVnode`函数用来进行判断是否是同一个vnode元素。源代码如下:


 

如图所示:


 

这里有两个重要元素:`key` : 开发者定义的”:key”;`sel `: 元素tagName+元素id+元素class。

sel的定义源码如下:


 

vNode构建函数:


 

第三是构建索引。


 

逻辑如图:


 


 

如何处理元素

尽量不新增/删除dom。如图下所示:


 

如果是相同vnode,源码如下:


 


 

开始比较

首先会进行时间复杂度O(n)的while循环,循环条件为“遍历旧节点数组&&遍历新节点数组,谁先遍历完循环就结束”。源码如下图:


 

在每次的循环过程中,会有两大类判断方法:

1)首尾比较&首尾序号


 

逻辑:如图上所示。首先在循环遍历前标记好新,旧节点数组的开始位置和结束位置的序号:oldStartIdx、oldEndIdx、newStartIdx、newEndIdx;其次在循环遍历的过程中采用“首首比较,尾尾比较,首尾比较"

源码如下:


 

如果数据为图上所示,那么根据首尾比较方法会有如下图所示结果,最终全部执行了更新操作:


 

2)索引比较

最坏情况,这里的时间复杂度也是O(n),即整个算法复杂度O(n)+O(n)。每次遍历的过程中可能存在"新数组节点新增/旧数组节点删除",那么前后对比就满足不了条件。这里逻辑会进入索引比较:比如这种情况:


 

那么循环中会执行一遍,创建旧数组的索引对象。从创建到比较的整个逻辑图如下:


 

这里的源码如下:


 

 

  • 当旧节点不存在新增的节点时,进行当前oldStartIdx位置的添加
  •  

 

源码如下:


 

 

  • 当旧数组存在节点,那么进行位置移动
  •  

 

源码:


 

3)当节点遍历完之后

会存在两种情况:新数组已经遍历完,但旧数组没有遍历完成;旧数组遍历完成,但新数组没有遍历完成。故源代码的判断如下:


 

 

  • 旧数组没有循环完成

 

旧数组没有循环完成的效果如下图所示:


 

这里注意一个点,我们每次的节点更新会移动序号,即使被删除的节点不在一块最终也会被首尾比较算法“摞在一块”(oldStartIdx~oldEndIdx)。上图所示更加明显。源码在这里就进行批量删除:


 

 

  • 新数组没有循环完成

 

效果如下图所示:


 

整体来说,有几个关键点:简单对比;创建旧数组的索引表;首位对比&首尾索引&vnode位置移动;索引添加/位移;剩余部分批量处理添加/删除

经过前后对比&索引的过滤后,只会存在新.末尾节点!==旧节点及之前的连续的新节点(!==旧节点),所以这里也被“摞在一块”,即 (newStartIdx~newEndIdx)。源码如下。这样,整个diff的对比算法就已经走完了。核心就是:前后对比+索引。


 


 

vue3.0对于diff比较前的优化

vue3.0针对“无脑”patchVnode进行了过滤--静态类型Vnode老版的源码:


 

这里,我们再重复下vue2.x系列的对比更新逻辑:


 

新版的vue3.0增加了静态类型Vnode。如果是静态类型的vnode,直接跳过更新,修改新节点引用即可。


 

comment类型目前翻到它的源码也只是更改引用,源码作者加上了一行注释。


 

补充一下,flagment碎片类型为新增的vnode类型,即:


 

vue3.0的过滤判断源码如下:


 


 

数组比较的应用

由于我们想监听数组的变化,参考了diff算法覆写类似的逻辑,用来在update,add,dels时,代码层面获取操作的具体节点明细(新旧节点的位置,内容)。希望本文对你有帮助。

作者:陈碧松

出处:https://mp.weixin.qq.com/s/-8-AkMqwXJX54r6Lzbr5rA



Tags:算法   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
导语 | 开发者工作中,研究代码逻辑常需要思考这个问题:数组变更后,具体变更了哪一些元素?变更的位置如何?本文作者陈碧松解析并覆写了针对数组变化的diff算法逻辑。希望本文对你...【详细内容】
2023-01-08  Tags: 算法  点击:(0)  评论:(0)  加入收藏
摘要Raft 是一种为了管理复制日志的一致性算法。它提供了和 Paxos 算法相同的功能和性能,但是它的算法结构和 Paxos 不同,使得 Raft 算法更加容易理解并且更容易构建实际的系...【详细内容】
2022-12-29  Tags: 算法  点击:(11)  评论:(0)  加入收藏
C语言几乎唯一的缺点就是,需要手动管理内存。抛开这点之外,我觉得其他语言都不如C语言[呲牙]所以,虽然自动内存管理比较复杂,但我还是给scf编译器框架加了静态的GC算法。在编程...【详细内容】
2022-12-27  Tags: 算法  点击:(14)  评论:(0)  加入收藏
只需上传一张照片或输入一段文字,几秒钟后,你就能得到一张与上传照片意象极为相似的艺术图画。这不是科幻电影,而是当前大火的AI绘画软件带来的视觉新体验。AI绘画即人工智能绘...【详细内容】
2022-12-09  Tags: 算法  点击:(39)  评论:(0)  加入收藏
选择排序pub fn selection_sort<T:Ord>(arr:&mut [T]) { let len = arr.len(); for left in 0..len { let mut smallest = left; for right in (left+...【详细内容】
2022-12-02  Tags: 算法  点击:(20)  评论:(0)  加入收藏
本文主要内容如下: 前言最近生产环境遇到一个问题:现象:创建工单、订单等地方,全都创建数据失败。初步排查:报错信息为duplicate key,意思是保存数据的时候,报主键 id 重复,而这些...【详细内容】
2022-11-15  Tags: 算法  点击:(28)  评论:(0)  加入收藏
算法最开始是数学概念,我国古代称之为“术”,最早出现在《周髀算经》和《九章算术》中。而现代计算机中的算法的定义,则是在阿朗佐&middot;丘奇 和他的学生艾伦&middot;图灵的...【详细内容】
2022-11-09  Tags: 算法  点击:(42)  评论:(0)  加入收藏
对 TikTok 算法的工作原理感到好奇吗?什么是 TikTok 算法?TikTok 算法是一个复杂的系统,旨在为应用主页上的用户内容提供服务 - 为您提供页面 (FYP)。就像Instagram 的探索页面...【详细内容】
2022-11-03  Tags: 算法  点击:(67)  评论:(0)  加入收藏
去年写了一篇文章手写一个虚拟DOM库,彻底让你理解diff算法介绍虚拟DOM的patch过程和diff算法过程,当时使用的是双端diff算法,今年看到了Vue3使用的已经是快速diff算法,所以也想...【详细内容】
2022-10-30  Tags: 算法  点击:(27)  评论:(0)  加入收藏
前言CPU (Central Processing Unit)作为整个冯&middot;诺依曼架构的控制与运算中心,终其一生都在执行没有边界的指令,用无差别的计算支撑起智能时代“算力取之不尽用之不竭”的...【详细内容】
2022-10-28  Tags: 算法  点击:(37)  评论:(0)  加入收藏
▌简易百科推荐
导语 | 开发者工作中,研究代码逻辑常需要思考这个问题:数组变更后,具体变更了哪一些元素?变更的位置如何?本文作者陈碧松解析并覆写了针对数组变化的diff算法逻辑。希望本文对你...【详细内容】
2023-01-08  闪现基因  今日头条  Tags:算法   点击:(0)  评论:(0)  加入收藏
摘要Raft 是一种为了管理复制日志的一致性算法。它提供了和 Paxos 算法相同的功能和性能,但是它的算法结构和 Paxos 不同,使得 Raft 算法更加容易理解并且更容易构建实际的系...【详细内容】
2022-12-29  互联网资讯看板   网易号  Tags:算法   点击:(11)  评论:(0)  加入收藏
选择排序pub fn selection_sort<T:Ord>(arr:&mut [T]) { let len = arr.len(); for left in 0..len { let mut smallest = left; for right in (left+...【详细内容】
2022-12-02  麦花香里说丰年    Tags:算法   点击:(20)  评论:(0)  加入收藏
B 树和 B+ 树是两种数据结构,构建了磁盘中的高速索引结构,因此不仅 MySQL 在用,MongoDB、Oracle 等也在用,基本属于数据库的标配常规操作。数据库要经常和磁盘与内存打交道,为了...【详细内容】
2022-11-25  java小悠  今日头条  Tags:B 树   点击:(39)  评论:(0)  加入收藏
本文主要内容如下: 前言最近生产环境遇到一个问题:现象:创建工单、订单等地方,全都创建数据失败。初步排查:报错信息为duplicate key,意思是保存数据的时候,报主键 id 重复,而这些...【详细内容】
2022-11-15  架构师之道  今日头条  Tags:雪花算法   点击:(28)  评论:(0)  加入收藏
算法最开始是数学概念,我国古代称之为“术”,最早出现在《周髀算经》和《九章算术》中。而现代计算机中的算法的定义,则是在阿朗佐&middot;丘奇 和他的学生艾伦&middot;图灵的...【详细内容】
2022-11-09  异步社区  今日头条  Tags:算法   点击:(42)  评论:(0)  加入收藏
去年写了一篇文章手写一个虚拟DOM库,彻底让你理解diff算法介绍虚拟DOM的patch过程和diff算法过程,当时使用的是双端diff算法,今年看到了Vue3使用的已经是快速diff算法,所以也想...【详细内容】
2022-10-30  街角小林  今日头条  Tags:算法   点击:(27)  评论:(0)  加入收藏
前言CPU (Central Processing Unit)作为整个冯&middot;诺依曼架构的控制与运算中心,终其一生都在执行没有边界的指令,用无差别的计算支撑起智能时代“算力取之不尽用之不竭”的...【详细内容】
2022-10-28  码洞  CSDN  Tags:算法   点击:(37)  评论:(0)  加入收藏
什么是散列表散列表又被称为哈希表,包含一个键key、一个值value它们之间的对应关系是一对一,散列表就提供了键key和值value的对应关系,基本结构如下。 键值不会重复所以通过键...【详细内容】
2022-10-25  Java面试365  今日头条  Tags:散列表   点击:(25)  评论:(0)  加入收藏
摘要深度学习在科学计算领域得到了广泛的应用,其算法被解决复杂问题的行业广泛使用。所有的深度学习算法都使用不同类型的神经网络来执行特定的任务。本文为大家带来基本的人...【详细内容】
2022-10-22  BigQuant  今日头条  Tags:算法   点击:(78)  评论:(0)  加入收藏
站内最新
站内热门
站内头条