前端知识体系图(前端知识体系思维导图)

作者:电脑培训网 2024-05-02 17:51:46 329

【前端知识体系回顾】Diff策略

目录

前端知识体系图(前端知识体系思维导图)

前言

传统Diff算法

反应差异

1.树差异

2.组件差异

3.元素差异

1)不使用钥匙时:

2)。密钥使用情况:

光纤架构

结论

前言

React的核心是虚拟DOM和Diff算法;

React在内存中维护一个虚拟DOM树。当数据发生变化时,它会自动更新虚拟DOM,获取新的虚拟DOM,然后使用Diff算法比较新旧虚拟DOM树,找到变化最小的一棵。部分,将变化的部分添加到队列中,最后批量将patch更新到实际DOM;

一、传统Diff算法

传统Diff算法的主要思想是如何用最少的操作步骤来修改DOM树;

通过最少的操作步骤将一棵树映射到另一棵t树,称为树编辑距离算法;

这种传统Difff算法的最大缺点是速度慢且性能极低。其时间复杂度只能达到O(n^3);

二、ReactDiff

diff算法的本质是寻找两个对象之间的差异,目的是尽可能地重用节点。

为了优化传统的diff算法,React做了两个假设:

1.两种不同类型的元素会产生不同的树。

2.开发者可以通过关键道具来提示哪些子元素在不同的渲染下可以保持稳定。

基于以上两个假设,React提出了三种优化diff算法的策略:

1.DOM节点的跨层移动操作很少,可以忽略。

2.拥有两个相同类型的组件将生成相似的树结构,拥有两个不同类型的组件将生成不同的树结构。

3.对于一组同级的子节点,可以通过唯一的key来区分

基于以上三种策略,React对diff算法进行了以下三个部分的优化。

1、treediff

React只对虚拟DOM树进行层次比较,没有考虑节点的跨级比较。它根据比较结果添加和删除节点。这样只需遍历一次虚拟DOM树就可以完成整个比较;

但是,如果发生跨级操作,React无法复用现有节点,而必须将其全部删除并重新创建,这会影响性能;因此,React官方建议尽可能避免跨级操作;

2、componentdiff

React是基于组件构建的。组件间比较采用的策略如下:

1)如果是同一类型的组件,首先使用shouldComponentUpdate()方法判断是否需要比较。如果返回true,则比较对应的DOM节点。否则,无需比较。

2)如果是不同类型的组件,则会将该组件判断为脏组件,从而替换整个组件下的所有子节点;

比如有两个组件,一A一B,虽然这两个组件结构相似但类型不同,但React不会比较它们,而是直接删除组件A并创建组件B;

1)对于不同类型的组件,默认不需要比较操作,可以直接重新创建。

2)对于同类型的组件,让开发者自定义shouldComponentUpdate()方法进行比较优化,减少组件不必要的比较。如果不自定义,shouldComponent()方法默认返回true,并且默认每次组件的数据发生变化时都会进行一次比较。

3、elementdiff

elementdiff涉及三个操作:移动、创建、删除;同级子节点是否使用key另行讨论

1)、不使用key的情况:

React比较新旧同级子节点,发现新集合中的B不等于旧集合中的A,因此删除A,创建B,以此类推。这样的话,前后相同的节点就会因为顺序的原因而不同。并被删除并重新创建,从而影响性能;

2)、使用key的情况:

React会先遍历新集合,并使用唯一键来判断旧集合中是否存在相同的节点。如果没有,请创建它。如果存在,则会判断是否需要进行移动操作,React也采用了一种移动操作的方法。非常高效的算法;

Elementdiff通过唯一键优化diff,通过复用现有节点来减少节点删除和创建操作;

React通过指定相应的diff策略,将O(n^3)复杂度问题转化为O(n)复杂度问题。

1)。通过层次比较策略优化树差异算法。

2)使用相同的类生成相似的树结构,不同的类生成不同的树结构以及shouldComponentUpdate策略来优化Componentdiff算法。

3)通过设置唯一的key策略来优化elementdiff算法

三、fiber架构

Fiber是React16之后的虚拟DOM思想:

Fiber可以理解为一个执行单元。每执行一个执行单元,react都会检查还剩多少时间,如果没有时间,就会放弃控制权;

首先,React向浏览器请求调度。如果浏览器在某一帧中还有空闲时间,就会判断是否有任务需要执行。如果不存在,则直接将控制权交给浏览器。如果存在则执行相应的任务。执行完成后,返回判断是否还有事件。如果有时间和任务要执行,则继续下一个任务,否则将控制权交给浏览器。

组织一个单元需要一个数据结构,使用传统的虚拟DOM很难对其进行划分。我们现在构建一个新的结构,我们称之为纤维;

ReactFiber使用链表实现,每个虚拟DOM都可以表示为一个Fiber;

关于纤维的内容很多,这里不再赘述。以后我会发表一篇关于光纤的博客;

结束语

明天写webpack!

相关推荐