react diff算法的运作原理?(一)

简介: react diff算法的运作原理?

前言


以下讲解的内容有:什么是react diff和diff的区别有哪些?


一、React diff是什么?


跟Vue一致,React通过引入Virtual DOM的概念,极大地避免无效的Dom操作,使我们的页面的构建效率提到了极大的提升


而diff算法就是更高效地通过对比新旧Virtual DOM来找出真正的Dom变化之处


传统diff算法通过循环递归对节点进行依次对比,效率低下,算法复杂度达到 O(n^3),react将算法进行一个优化,复杂度姜维O(n),两者效率差距如下图:


7485d2714d371e82b41fd21d9e116fa8_5b29000d85144444a56c0dc7eb6629df.png


二、原理


react中diff算法主要遵循三个层级的策略:


tree 层级


conponent 层级


element 层级


tree层级


DOM节点跨层级的操作不做优化,只会对相同层级的节点进行比较


342cc269a9aa71f65ccbad9395b9652b_b39b3e5226ee450ea066004cd5734169.png


只有删除、创建操作,没有移动操作,如下图:


4cb4af2a2a7ea43b351b67c598bd483d_67c896ec0c114a7392de81c1c172c181.png


react发现新树中,R节点下没有了A,那么直接删除A,在D节点下创建A以及下属节点


上述操作中,只有删除和创建操作


conponent层级


如果是同一个类的组件,则会继续往下diff运算,如果不是一个类的组件,那么直接删除这个组件下的所有子节点,创建新的


79280e009831450d1c02fa16e4297b4f_be3ab6ce1ccd4bf0a05c4f1278ad3e4a.png


当component D换成了component G 后,即使两者的结构非常类似,也会将D删除再重新创建G。


element层级


对于比较同一层级的节点们,每个节点在对应的层级用唯一的key作为标识


提供了 3 种节点操作,分别为 INSERT_MARKUP(插入)、MOVE_EXISTING (移动)和 REMOVE_NODE (删除)


如下场景:


c7ac0dc38b0a53948db9c63fdd8f239b_4abf7521eab5491b8e99bc26040135f8.png


通过key可以准确地发现新旧集合中的节点都是相同的节点,因此无需进行节点删除和创建,只需要将旧集合中节点的位置进行移动,更新为新集合中节点的位置


流程如下表:


33ee95ba94bc7b22e880da1aab27f91f_a9faf0b9942c4bd9ab29d47c87b36ae9.png


index: 新集合的遍历下标。

oldIndex:当前节点在老集合中的下标

maxIndex:在新集合访问过的节点中,其在老集合的最大下标

如果当前节点在新集合中的位置比老集合中的位置靠前的话,是不会影响后续节点操作的,这里这时候被动字节不用动。

操作过程中只比较oldIndex和maxIndex,规则如下:


当oldIndex>maxIndex时,将oldIndex的值赋值给maxIndex

当oldIndex=maxIndex时,不操作

当oldIndex<maxIndex时,将当前节点移动到index的位置

diff过程如下:


节点B:此时 maxIndex=0,oldIndex=1;满足 maxIndex< oldIndex,因此B节点不动,此时maxIndex= Math.max(oldIndex, maxIndex),就是1

节点A:此时maxIndex=1,oldIndex=0;不满足maxIndex< oldIndex,因此A节点进行移动操作,此时maxIndex= Math.max(oldIndex, maxIndex),还是1

节点D:此时maxIndex=1, oldIndex=3;满足maxIndex< oldIndex,因此D节点不动,此时maxIndex= Math.max(oldIndex, maxIndex),就是3

节点C:此时maxIndex=3,oldIndex=2;不满足maxIndex< oldIndex,因此C节点进行移动操作,当前已经比较完了

当ABCD节点比较完成后,diff 过程还没完,还会整体遍历老集合中节点,看有没有没用到的节点,有的话,就删除


目录
相关文章
|
4天前
|
JavaScript 算法 开发者
vue diff算法介绍
vue diff算法介绍
15 2
|
2天前
|
JavaScript 前端开发 算法
React中的DOM diff算法是如何工作的
React的DOM diff算法通过对比新旧虚拟DOM树找到最小更新策略,提高组件更新效率。它生成并比较虚拟DOM,按类型、属性和&quot;key&quot;逐节点检查。不同类型节点直接替换,属性不同则更新属性,相同则递归比较子节点。确定DOM操作后批量执行,减少对真实DOM的访问,优化性能。然而,在复杂场景下可能有性能问题,可借助shouldComponentUpdate、memo或PureComponent等进行优化。
|
3天前
|
Arthas 监控 算法
JVM工作原理与实战(二十五):堆的垃圾回收-垃圾回收算法
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了垃圾回收算法评价标准、标记清除算法、复制算法、标记整理算法、分代垃圾回收算法等内容。
17 0
JVM工作原理与实战(二十五):堆的垃圾回收-垃圾回收算法
|
9天前
|
机器学习/深度学习 自然语言处理 算法
机器学习算法原理与应用:深入探索与实战
【5月更文挑战第2天】本文深入探讨机器学习算法原理,包括监督学习(如线性回归、SVM、神经网络)、非监督学习(聚类、PCA)和强化学习。通过案例展示了机器学习在图像识别(CNN)、自然语言处理(RNN/LSTM)和推荐系统(协同过滤)的应用。随着技术发展,机器学习正广泛影响各领域,但也带来隐私和算法偏见问题,需关注解决。
|
10天前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习专栏】层次聚类算法的原理与应用
【4月更文挑战第30天】层次聚类是数据挖掘中的聚类技术,无需预设簇数量,能生成数据的层次结构。分为凝聚(自下而上)和分裂(自上而下)两类,常用凝聚层次聚类有最短/最长距离、群集平均和Ward方法。优点是自动确定簇数、提供层次结构,适合小到中型数据集;缺点是计算成本高、过程不可逆且对异常值敏感。在Python中可使用`scipy.cluster.hierarchy`进行实现。尽管有局限,层次聚类仍是各领域强大的分析工具。
|
10天前
|
机器学习/深度学习 算法 前端开发
【Python机器学习专栏】集成学习算法的原理与应用
【4月更文挑战第30天】集成学习通过组合多个基学习器提升预测准确性,广泛应用于分类、回归等问题。主要步骤包括生成基学习器、训练和结合预测结果。算法类型有Bagging(如随机森林)、Boosting(如AdaBoost)和Stacking。Python中可使用scikit-learn实现,如示例代码展示的随机森林分类。集成学习能降低模型方差,缓解过拟合,提高预测性能。
|
11天前
|
机器学习/深度学习 算法 数据挖掘
【视频】支持向量机算法原理和Python用户流失数据挖掘SVM实例(下)
【视频】支持向量机算法原理和Python用户流失数据挖掘SVM实例(下)
|
1天前
|
存储 算法 数据可视化
基于harris角点和RANSAC算法的图像拼接matlab仿真
本文介绍了使用MATLAB2022a进行图像拼接的流程,涉及Harris角点检测和RANSAC算法。Harris角点检测寻找图像中局部曲率变化显著的点,RANSAC则用于排除噪声和异常点,找到最佳匹配。核心程序包括自定义的Harris角点计算函数,RANSAC参数设置,以及匹配点的可视化和仿射变换矩阵计算,最终生成全景图像。
|
1天前
|
算法 Serverless
m基于遗传优化的LDPC码NMS译码算法最优归一化参数计算和误码率matlab仿真
MATLAB 2022a仿真实现了遗传优化的归一化最小和(NMS)译码算法,应用于低密度奇偶校验(LDPC)码。结果显示了遗传优化的迭代过程和误码率对比。遗传算法通过选择、交叉和变异操作寻找最佳归一化因子,以提升NMS译码性能。核心程序包括迭代优化、目标函数计算及性能绘图。最终,展示了SNR与误码率的关系,并保存了关键数据。
11 1
|
2天前
|
算法 调度
考虑需求响应的微网优化调度模型【粒子群算法】【matlab】
考虑需求响应的微网优化调度模型【粒子群算法】【matlab】