react diff策略

React通过引入Virtual DOM的概念,极大地避免无效的Dom操作。将时间复杂度从O3降到了O1,归功于react的 diff策略。

实现原理:

  • Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计
  • 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构
  • 对于同一层级的一组子节点,它们可以通过唯一 id 进行区分

在上面三个策略的基础上,React 分别将对应的tree diff、component diff 以及 element diff 进行算法优化,极大地提升了diff效率。

 

tree diff

React 对树的算法进行了简洁明了的优化,即对树进行分层比较,两棵树只会对同一层次的节点进行比较。相同层的元素,如果是同一类元素(同一种html标签),则不会销毁该dom,而会根据新的dom属性来更新旧的dom的属性,如果不是同一种标签则会直接销毁并且销毁其所有子节点,然后创建新的dom插入。

component diff

  • 如果是同一类型的组件,按照原策略继续比较 Virtual DOM 树即可。
  • 如果不是,则将该组件判断为 dirty component,从而替换整个组件下的所有子节点。
  • 对于同一类型的组件,有可能其 Virtual DOM 没有任何变化,如果能够确切知道这点,那么就可以节省大量的 diff 运算时间。因此,React允许用户通过shouldComponentUpdate()来判断该组件是否需要进行diff算法分析,但是如果调用了forceUpdate方法,shouldComponentUpdate则失效。

element diff

当节点处于同一层级时,diff 提供了 3 种节点操作,分别为 INSERT_MARKUP (插入)、MOVE_EXISTING (移动)和 REMOVE_NODE (删除)。

相同的节点,仅仅是位置发生了变化,但却需要进行繁杂低效的删除、创建操作,其实只要对这些节点进行位置移动即可。React针对这一现象提出了一种优化策略:允许开发者对同一层级的同组子节点,添加唯一 key 进行区分

如果新旧dom树上的同一层级里存在相同key的dom则会直接实用原来的key的元素并且移动dom的位置,然后继续比对dom的类型和属性并更新,这会减少很多dom的创建和销毁,大部分情况下是可以提高性能的,但是在极端情况下并不会带来性能的提示,比如将最后一个元素提到第一位,react实际上是把所有前面的元素都挪了一遍位置,将它们移动到后面,如果不加key,react则只会更新最后一个dom的属性,反而得不偿失。所以在使用key的时候可以考虑下场景,是否真的能提高性能(99%的情况会提高,除非是很简单的一个基本标签,但这也就无所谓了,主要为了组件的key,防止组件频繁的创建和销毁,因为组件里往往有着比较深的下级dom,全部销毁和创建比较浪费性能,并且会触发组件的生命周期)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值