老生常谈React的diff算法原理-面试版

第一次发文章 not only(虽然)版式可能有点烂 but also (但是)最后赋有手稿研究 finally看完他你有收获

diff算法:对于update的组件,他会将当前组件与该组件在上次更新是对应的Fiber节点比较,将比较的结果生成新的Fiber节点。

! 为了防止概念混淆,强调

一个DOM节点,在某一时刻最多会有4个节点和他相关。

- 1.current Fiber。如果该DOM节点已在页面中,current Fiber代表该DOM节点对应的Fiber节点。
- 2.workInProgress Fiber。如果该DOM节点将在本次更新中渲染到页面中,workInProgress Fiber代表该DOM节点对应的Fiber节点。
- 3.DOM节点本身。
- 4.JSX对象。即ClassComponent的render方法的返回结果,或者FunctionComponent的调用结果,JSX对象中包含描述DOM节点信息。
diff算法的本质上是对比1和4,生成2。
Diff的瓶颈以及React如何应对
由于diff操作本身也会带来性能损耗,React文档中提到,即使在最前沿的算法中
将前后两棵树完全比对的算法的复杂程度为 O(n 3 ),其中 n 是树中元素的数量。

如果在React中使用了该算法,那么展示1000个元素所需要执行的计算量将在十亿的量级范围。
这个开销实在是太过高昂。

所以为了降低算法复杂度,React的diff会预设3个限制:

 1.同级元素进行Diff。如果一个DOM节点在前后两次更新中跨越了层级,那么React不会尝试复用他。
 2.不同类型的元素会产生出不同的树。如果元素由div变为p,React会销毁div及其子孙节点,并新建p及其子孙节点。
 3.者可以通过 key prop来暗示哪些子元素在不同的渲染下能保持稳定。

那么我们接下来看一下Diff是如何实现的

参考 前端react面试题详细解答

我们可以从同级的节点数量将Diff分为两类:

 1.当newChild类型为object、numberstring,代表同级只有一个节点
- 2.当newChild类型为Array,同级有多个节点

单节点diff

以类型Object为例,会进入这个函数reconcileSingleElement

这个函数会做如下事情:

让我们看看第二步判断DOM节点是否可以复用是如何实现的。

从代码可以看出,React通过先判断key是否相同,如果key相同则判断type是否相同,只有都相同时一个DOM节点才能复用。

这里有个细节需要关注下:

1.当child !== null且key相同且type不同时执行deleteRemainingChildren将child及其兄弟fiber都标记删除。

2.当child !== null且key不同时仅将child标记删除。

例子:当

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值