React之childExpirationTime

前言:
在上篇文章React源码解析之workLoop
中有提到 React 利用 childExpirationTime,来跳过子树的遍历及渲染,本文讲下 childExpirationTime 的含义和做用。app

expirationTime 是如何产生的?
每当节点调用setState,就会产生一个update而且计算出一个expirationTime(关于 expirationTime 的计算,请看:React源码解析之ExpirationTimeoop

childExpirationTime 是如何产生的?post

因为 React 的更新是从FiberRoot开始的,因此当某一节点发生更新时,React 会向上遍历,直至找到FiberRoot性能

在向上遍历的过程当中,会顺便找到发生更新节点的父节点,当找到父节点的时候,因为它们的子节点发生了更新,因此会在父节点上设置childExpirationTime3d

注意:
(1)多个子节点更新,取最大的expirationTime做为父节点的childExpirationTime
每一个父节点上只会有一个expirationTime和一个childExpirationTime,当有多个子节点都有更新时,取子节点最大的(优先级最高的)expirationTime,做为父节点的childExpirationTimecode

(2)单个子节点屡次更新,取某次更新出的最大的expirationTime做为自身的expirationTimecdn

childExpirationTime 的做用?
在 React 自上而下更新 fiber 树的时候,每一个节点会执行update方法,根据expirationTimechildExpirationTime的优先级大小来判断该节点自己、该节点的子节点是否须要在本次渲染(这一帧)的时候更新。对象

举个例子:
上图的List产生的更新的expirationTime为 250(假设的,其实是个时间戳),Span1expirationTime为 100,Span2expirationTime为 200,明显 Span2 的优先级高于 Span1,因此ListchildExpirationTime设为 200blog

其余节点均无更新,expirationTime=NoWork即 0,当 React 自上而下遍历到List节点时,发现它的 fiber 对象的expirationTime大于childExpirationTime,因此会优先执行List自身的更新,若是这一帧留给 React 的时间还够的话,会执行其子节点的更新,不然就跳过,放在下一帧执行rem

能够想象,若是不设置childExpirationTime的话,还要继续向下遍历获取子节点的expirationTime再拿去跟父节点的expirationTime比较,看谁先更新,是浪费性能的作法。


(完)

相关文章
相关标签/搜索