【React】diff算法

diff算法作为Virtual DOM的加速器,其算法的改进优化是React整个界面渲染的基础和性能的保障,同时也是React源码中最神秘的,最不可思议的部分。


传统diff、React diff

传统diff算法

  • 通过循环递归对节点进行依次对比,算法复杂度达到 O(n^3)
  • 如果要展示1000个节点,得执行上亿次比较。。即便是CPU快能执行30亿条命令,也很难在一秒内计算出差异。

React diff:

  • React15对传统的diff做了一些限制,使得时间复杂度变为了O(n)。
  • 调和:将Virtual DOM树转换成actual DOM树的最少操作的过程
  • diff算法:调和的具体实现。
  • react的 diff 能减少到o(n)依靠的是react diff的三大策略tree diff component diff element diff

React 三大策略

tree diff:

相同层级:

  • 首先,进行同级比较,并非循环比较。
  • 这样比较次数就降为一层一次,时间复杂度直接降为O(n)
  • 如果同级相同位置节点不一样,则直接删除替换,简单粗暴。
    在这里插入图片描述

跨层级:

  • 对于不同层级的节点,只有创建和删除操作
createA-->createB-->createC-->deleteA

在这里插入图片描述

component diff:

  • component diff相当于是子树的diff,基本方案和tree diff是一致的
  • 如果如下图D变为G,那么直接删除D这一整棵树,然后重新渲染G树。

在这里插入图片描述

element diff:

对于同一节点的元素,diff算法提供了三种操作:插入、移动、删除。分别为INSERT_MARKUP(插入)MOVE_EXISTING(移动),REMOVE_NODE(删除)

  • INSERT_MARKUP:新的组件类型不在旧集合中,即全新的节点,需要对新节点进行插入操作。
  • MOVE_EXISTING:旧集合中有新组件类型,且element是可更新的类型,这时候就需要做移动操作,可以复用以前的DOM节点。
  • REMOVE_NODE:旧组件类型,在新集合里也有,但对应的element不同则不能直接复用和更新,需要执行删除操作,或者旧组件不在新集合里的,也需要执行删除操作。

React中key的引入、性能的提升

未引入key之前的操作:

  • 老集合中包含节点:A、B、C、D
  • 更新后的新集合中包含节点:B、A、D、C
  • 此时新老集合进行 diff 差异化对比,发现 B != A,则创建并插入 B 至新集合,删除老集合 A;以此类推,创建并插入 A、D 和 C,删除 B、C 和 D。
  • 都是相同的节点,但由于位置发生变化,导致需要进行繁杂低效的删除、创建操作,其实只要对这些节点进行位置移动即可。
    在这里插入图片描述

引入key之后的操作:

  • 此时的操作,是B、D不做任何操作,AC移动到相应位置【前提是都有相同的唯一key】
  • 如果,此时的key不相同,全都发生了变化,那么节点全都是要删除重新构建,将会消耗大量性能。
    在这里插入图片描述

虚拟DOM中key的作用:

  • key是虚拟DOM对象的标识,在更新显示时key起着极为重要的作用。
  • 当状态中的数据发生变化时,React会根据新数据 生成新的虚拟DOM,随后React进行新虚拟DOM旧虚拟DOM的diff比较,比较规则如下:
    • 1、 旧虚拟DOM中找到与新虚拟DOM相同的key:
      • 若虚拟DOM中内容没变, 直接使用之前的真实DOM
      • 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
    • 2、 旧虚拟DOM中未找到与新虚拟DOM相同的key:
      • 根据数据创建新的真实DOM,随后渲染到到页面
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南栀~zmt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值