Diff算法中到底做了什么操作

✅作者简介:大家好我是无处不楼台,是一个什么都会一点的大前端小白博主!
个人主页:无处不楼台的博客_CSDN博客-JavaScript学习,项目开发,node学习领域博主
系列专栏:知识体系梳理
如果觉得博主的文章还不错的话,请三连支持一下博主哦  

Diff算法中到底做了什么操作_第1张图片

目录

前言

传统Diff算法

React Diff

1、tree diff

2、component diff

3、element diff

1)、不使用key的情况:

2)、使用key的情况:

fiber架构

结束语


前言

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

        React在内存中维护一颗虚拟DOM树,当数据发生改变时,会自动的去更新虚拟DOM,获得一个新的虚拟DOM,然后通过Diff算法,比较新旧虚拟DOM树,找出最小的有变化的部分,将这个变化的部分(Patch)加入队列,最终批量的更新这个Patch到实际DOM中;


一、传统Diff算法

        传统的Diff算法的主要思想就是如何用最小的操作步数去修改DOM树;

        将一颗树通过最小操作步数映射到另一颗t树,这种算法叫做树编辑距离算法;

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


二、React Diff

        diff算法的本质就是:找出两个对象之间的差异,目的是尽可能做到节点复用。

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

1、两个不同类型的元素会产生出不同的树

2、开发者可以通过key props 来暗示哪些子元素在不同的渲染下能保持稳定

        基于这上述两个假设,React针对性的提出了三个策略以对diff算法进行优化:

1、DOM节点跨层级的移动操作特别少,可以忽略不记

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

3、对于同一层级的一组子节点,它们可以通过唯一key进行区分

        基于上述三个策略,react分别对以下三个部分进行了diff算法优化

1、tree diff

        React只对虚拟DOM树进行分层比较,不考虑节点的跨层级比较,根据对比结果,进行节点的新增和删除,如此,只需要遍历一次虚拟DOM树,就可以完成整个对比;

        但是,如果出现了跨层级的操作,react是无法复用已有的节点,而是要整个删除,并重新创建,这会影响性能;所以react官方推荐尽量避免跨层级的操作;

2、component diff

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

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

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

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

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

2)、对于同类型的组件,通过让开发人员自定义shouldComponentUpdate()方法来进行比较优化,减少组件不必要的比较。如果没有自定义,shouldComponent()方法默认返回true,默认每次组件发生数据变化时都进行比较

3、element diff

        element diff涉及三种操作:移动、创建、删除;对于同一层级的子节点,对于是否使用key分别进行讨论

1)、不使用key的情况:

        React对新旧同一层级的子节点对比,发现新集合中的B不等于老集合中的A,于是删除A,创建B,依次类推,这样的话,前后相同的节点,都会因为顺序的不同而被删除和重新创建,从而影响性能;

2)、使用key的情况:

        React首先会对新集合进行遍历,通过唯一key来判断老集合中是否存在相同的节点,如果没有则创建,如果存在,则判断是否需要进行移动操作,并且react对于移动操作也采取了一种很高效的算法;

        element diff就是通过唯一key来进行diff优化,通过复用已有的节点,减少节点的删除和创建操作;


        React通过指定对应的diff策略,将O(n^3)复杂度问题转换成O(n)的复杂度问题

1)、通过分层对比策略,对tree diff进行算法优化

2)、通过相同类生成相似树形结构,不同类生成不同树形结构以及shouldComponentUpdate策略,对Component diff进行算法优化

3)、通过设置唯一key策略,对element diff进行算法优化


三、fiber架构

        fiber是React16之后的一个虚拟DOM思想:

        fiber可以理解为一个执行单元,每次执行完一个执行单元,react就会检查现在还剩多少时间,如果没有时间则将控制权让出去;

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

        组织一个单元需要一个数据结构,用传统的虚拟DOM很难再分割,我们现在构造一个新的结构,我们称之为fiber;

        React Fiber就是采用链表实现的,每个虚拟DOM都可以表示为一个fiber;

        fiber内容比较多,这里就不多论述,后续会专门出一篇关于fiber的blog;


结束语

       明天写webpack相关内容!!!

你可能感兴趣的:(知识体系梳理,前端,javascript,开发语言,css3,html)