React16源码: React中ReactFiberScheduler的expirationTime及nextExpirationTimeToWorkOn的源码实现

React源码分析(二)=> Reac初次渲染分析 Reac初次渲染分析 源码基于React 16.8.6, 内容极长, 必须配合源码一起来看 单步调试的例子: `ReactDOM.render('hello', document.getElementById('root'))`; 下文基于这个例子来一步一步分析. 阅读详情

expirationTime 和 nextExpirationTimeToWorkOn


1 )概述

  • 这两个值在整个 render 以及 commit 的过程当中,都起着非常重要的一个作用

  • 为什么react又需要去设置两个值来制定一些优先级相关的内容?

  • expirationTime 作用在渲染之前的,而 nextExpirationTimeToWorkOn 则是作用在渲染时的

  • 为什么说 expirationTime 是作用在渲染前的呢?

    • 因为 expirationTime 它发生作用的地方
    • 比如说在 requestWork 的时候,去调用 scheduleCallbackWithExpirationTime(root, expirationTime);
    • 这个时候就是传入的 expirationTime 是 root.expirationTime
    • 往前找, 在 scheduleWork 中 调用requestWork时,这里可以验证
      • const rootExpirationTime = root.expirationTime; requestWork(root, rootExpirationTime)
    • scheduleCallbackWithExpirationTime 这个函数
      • 是拿这个 expirationTime 参数来计算出设置在 reactschedule 里面的
      • 这个时间片更新的 callback,它在什么时间点是过期的一个行为
    • 而在 requestWork 里面,判断是否要去调用异步的时间片更新的方式,还是通过同步的方式去更新
      • 就是根据判断 expirationTime 是否等于 Sync 来进行的, 参考这里
    • 所以在这个过程当中,可以发现 root.expirationTime 决定了是否使用异步的方式来进行一个react的更新
    • 那么异步的方式跟同步的方式区别
      • 就是会拿到一个 deadline
      • 在我们执行 performWork 的时候,有一个 deadline 的一个对象
      • 在进行 workLoop的时候,是要每执行完一个单元要来进行判断一下这个 deadlineobject 是否已经过期
      • 而对于我们调用 performSyncWork 来进行的更新是完全没有这个考虑的
        • 是一条路走到黑,整棵树更新完之后,然后立马进行一个提交
        • 中间没有一个可以中断的一个过程
      • 在调用 performSyncWork 的时候,最终调用了 performWork
      • 注意,在 16.6.3 这个版本及后续版本,引入了 isYieldy 属性来替代 deadline 对象
      • isYieldy 更加简单,只是一个布尔值,用于指示当前任务是否可以被中断
      • 然后传入的是 Sync 以及 后面 isYieldy 为 false, 对于 false 时,进入下面的判断和while循环,参考
      • 这里,performWorkOnRoot 的第三个参数 isYieldy 是 写死的 false, 在函数内部直接传递给 renderRoot 函数
    • expirationTime 的作用主要发生进入更新新前,也就是进入 performWork 之前
    • 来确定是否要使用时间片的更新方式来进行一个react的整体的渲染
    • 使用时间片的更新方式会让整体的页面上面的一些性能的分配会更合理一点
      • 比如说把更高的优先级留给浏览器,要展现动画要进行一些计算
      • 而对于react,认为这个任务是比较低优先级的,所以可以分几次来进行一个完成
  • 而 nextExpirationTimeToWorkOn 有什么作用呢?

    • nextExpirationTimeToWorkOn 只出现在 renderRoot 中出现2次
    • 第一次是在 函数开始,它设置了一个变量,const expirationTime = root.nextExpirationTimeToWorkOn;
    • 第二次出现了是在 函数的结尾, 在这个条件下 else if (!root.didError && isYieldy){} 下设置
      • const suspendedExpirationTime = (root.nextExpirationTimeToWorkOn = expirationTime);
      • 它是在更新的过程当中,来确定我们这一次渲染更新的过程,它的任务的优先级的
    • 可以看一下,一开始拿到了这个 expirationTime 之后,接下去怎么走
      • 它会比较 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {}
        • 只要符合这个条件,就会设置 nextRenderExpirationTime = expirationTime;
        • 可以看到 nextRenderExpirationTime 它是一个公共全局变量,在不同的条件下赋予记录不同的值
        • 也就是在满足这个条件下,nextRenderExpirationTime 就是之前的 root.nextExpirationTimeToWorkOn
        • 接下去,看 nextRenderExpirationTime 这个变量在哪些地方发挥作用
          • 在 performUnitOfWork 中,调用 beginWork 中, 会传入这个 nextRenderExpirationTime
          • 这个参数在 beginWork 的时候,它会有什么用呢?
            • function beginWork(current: Fiber | null, workInProgress: Fiber, renderExpirationTime: ExpirationTime){}
            • 从上面到这里,可知道,这里传进来的 renderExpirationTime 就是 上面的 root.nextExpirationTimeToWorkOn
            • 这个值有一个非常关键的作用,就是用来比较我们当前的节点是否有任务
            • 在这一次渲染周期当中要被执行,在这边它获取了每一个节点上面的 expirationTime
              • 即:const updateExpirationTime = workInProgress.expirationTime;
            • 每个节点的 expirationTime 跟 root 的 expirationTime 是完全不一样的
            • 每个 fiber 节点的 expirationTime 只是用来记录当前这个节点上面
            • 比如说像是 class component 上面创建的所有的update中优先级最高的那个update
            • 也就是它的 updateExpirationTime 就相当于是说这个节点上面最高优先级的任务
            • 而通过对比 root.nextExpirationTimeToWorkOn,如果在这个节点上
            • 它优先级最高的那个 expirationTime 仍然要小于 renderExpirationTime (root.nextExpirationTimeToWorkOn)
            • 那么它是可以直接被跳过这次更新的,跳过更新的标志是下面的 return bailoutOnAlreadyFinishedWork
            • if (oldProps === newProps && !hasLegacyContextChanged() && updateExpirationTime < renderExpirationTime) {}
            • 因为只要符合其中一个,这个更新就可以被跳过
        • 所以说 nextExpirationTimeToWorkOn,它是用来标志这一次更新当中的任务的优先级的
        • 通过对比它跟每一个节点自身的 expirationTime
        • 它就可以判断这个节点是否在这一次更新流程当中,需要被更新,需要被执行
  • 基于以上,有时候可以通过强制指定,比如强制指定 root.expirationTime = Sync

  • 让它在下一次执行更新之前来使用 performSyncWork 这种方式来通过同步的方式去渲染任务

  • 比如说, 在 renderRoot 中 参考

    const suspendedExpirationTime = (root.nextExpirationTimeToWorkOn = expirationTime);
    const rootExpirationTime = (root.expirationTime = Sync);
    
    • 通过这两个指定,在下一次更新,就是下一次回到 performWork 的循环当中的时候
    • 下一个被更新到的 root 仍然是这个 root,并且它的更新模式是要通过 Sync 的模式来进行更新
    • 同时它要更新的任务的优先级,仍然是我们这一次更新的任务的优先级
  • 所以这就是这两个值它的作用, 通过指定它们来指定更新模式以及更新任务的优先级

React-从源码分析React Fiber工作原理 本文的demo仓库在https://github.com/qiqingjin/blog/tree/master/React_Redux,喜欢请star哟~ 为什么要重写React React16 以前 React16 以前,对virtural dom的更新和渲染是同步的。就是当一次更新或者一次加载开始以后,diff virtual dom并且渲染的过程是一口气完成的。如果组件... 阅读详情

相关推荐

hi3519dv500 os04a10输入调试

因该sensor接在soc端的iic6,在驱动中(Hi3519DV500_SDK_V2.0.1.1\smp\a55_linux\source\mpp\cbb\isp\user\sensor\hi3519dv500\omnivision_os04a10\os04a10_sensor_ctl.c)注意总线的选择。mem_process_isolation=1 改为 mem_process_isolation=0。2、OT_MIPI_SET_HS_MODE配置为LANE_DIVIDE_MODE_1。

linus 3174

一文吃透 React Expiration Time

Expiration Time 概念 首先 Expiration Time 到底是什么呢? 根据英文直接翻译可知,到期时间或者过期时间。在React中到期时间概念又如何理解,我们不妨从它的作用入手理解到底是什么概念。 Expiration Time 作用 在 React 中,源码位置是在 准备阶段 updateContainer 的位置 调用 computeExpirationForFiber 计算时间,这里是在准备阶段创建好React的更新对象,为后面的后面 React 调度做准备。它代表的是 任务在未来

开源世界 629

大整数因数分解工具——yafu

可以将大整数放在一个新建文件中——data.txt,最后面一定要换行,不然会出现eof;done processing batchfile,运行命令。2.点击设置——系统——系统信息——高级系统设置——环境变量——点击PATH(上下都可以)——新建 添加yafu-x64.exe 所在路径——点击确定。,如果整数数过长,会出现错误mismatched parens;1.找到yafu-x64.exe 所在的文件路径。如果出现以下图像,说明配置成功。3.打开cmd,输入。

l2ohvef的博客 6156

React 源码讲解第 6 节- expirationTime 公式

本节主要讲解 expirationTime 时间计算公式。

杏子 1368

STM32单片机远程升级

stm32远程升级

fang_yang_wa的博客 1万+

win10下面安装MTK USB VCOM 驱动

win10下面安装MTK USB VCOM 驱动1.概述2.驱动准备3.主要步骤3.1禁用win10对没有签名驱动限制3.2通过设备管理器安装mtk usb vcom驱动3.3工具版本问题4.禁用win10对没有签名的驱动限制4.1在设置中打开 更新和安全4.2进入恢复4.3在高级启动中点击立即重新启动4.4电脑重启后的几个动作5.通过设备管理器安装MTK USB VCOM 驱动5.1准备驱动5....

qimi123456的专栏 3万+

React16源码: React中更新阶段中不同类型的expirationTime之pendingTime,suspendedTime以及pingedTime的源码实现

现在发现,3种 expirationTime 的处理最终都调用了。下面是 renderRoot 中的一段代码。2.2 关于 suspendedTime。2.1 关于 pendingTime。

Wang的专栏 1014

博途的HMI(触摸屏)的应用

触摸屏(HMI):用于控制PLC,可认为是小型上位机(用于控制PLC的都可认为是上位机)上位机(PC Station):将触摸屏升级为电脑----工控机(工业控制的机器)用博途编写西门子的触摸屏和上位机。

王阿妹小天才的博客 2679

React Work Loop 原理

背景 - 前端体验优化 为了让 React 在检测到数据变化需要重新渲染界面的时候不会阻塞浏览器主线程,从而让用户交互体验更流畅,React 团队提出了 Work Loop 的概念,将任务拆分成小的模块,在每一个任务完成后都检测是否当前有优先级更高的任务(例如:用户与浏览器的交互),有则优先执行优先级更高的任务,没有则继续执行下一个任务。 (声明:本文所解析的所有逻辑都是为了大家能更好的通...

GuoZebin的博客 997

多IMU车载GNSS/INS数据集及介绍

文章目录前言非常棒的GINS数据集采集轨迹采集时间MEMS IMU详细信息IMU测量值方程及相关误差建模参考噪声参数安装参数文件格式描述 前言 “本文作者感谢武汉大学多源智能导航实验室和牛小骥教授提供了本文所需的GNSS/INS数据集。” 本博文介绍数据集链接为多IMU车载GNSS、INS数据集,欢迎大家下载,由于是开源数据集,因此下载不需要积分 非常棒的GINS数据集 这是一套非常好的用于GNSS/INS组合导航应用的车载数据集,本数据集采集于湖北省武汉市一处工业园区,为开阔天空场景,GNSS R

十八与她的博客 6443

Unity3D实现自定义河流路径或泥石流路径

此工具是一个插件,插件很好用,可以根据地形编辑河流的走向以及宽度,也可以发挥想象编辑成其他的效果,比如泥石流效果,岩浆效果,小溪,或者大江或者大河等等博客将会介绍可以编辑河流的工具的使用。希望这篇博客对Unity的开发者有所帮助。大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。提示:以下是本篇文章正文内容,下面案例可供参考本次总结的就是工具的使用, 有需要会继续增加功能不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒!

心疼你的一切博客 5271

React16源码: React中的schedule调度整体流程

React Fiber Scheduler 是 react16 最核心的一部分,这块在这个包中这个包的核心是 fiber reconciler,也即是 fiber 结构fiber的结构帮助我们把react整个树的应用,更新的流程,能够拆成每一个fibrer对象为单元的一个更新的流程这种单元的形式把更新拆分出来之后,给每个不同的任务提供一个优先级,以及我们在更新的过程当中,可以中断因为我们记录更新到了哪一个单元,中断了之后,可以过一会儿再回过头来,继续从这个单元开始,继续之前没有做完的更新。

Wang的专栏 1604

MIKE水动力笔记13_数字化海图2之克里金插值

在进行MIKE水动力建模之初,需要准备好水深数据,本专题系列博文主要讲解如何将扫描版JPG格式海图数据在ArcGIS中进行数字化并制作成xyz水深地形数据,用的克里金插值方法,仅供参考。

晏长街的博客 2881

React16源码: React中的expirationTime过期时间的计算源码实现

先看expirationTime相关的源代码,这里是异步的计算方式,它会有一个过期时间,异步任务优先级比较低,可以被打断,防止一直被打断导致不能执行,所以React给它设置了 expirationTime 过期时间,也就是在这个时间之前,都可以打断,但是如果某个时间点发现任务已经过期了,还没有被执行,则强制执行该任务

Wang的专栏 1851

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

react源码阅读4 ExpirationTime

react更新中优先级依赖的标识ExpirationTime。阅读React包的源码版本为16.8.6。   这一章节,让我们抛弃掉react代码中的联系,单纯的来看ExpirationTime以及一些计算方式。 ExpirationTime是什么。   ExpirationTime是一个数字,你可以在react-reconciler包下的ReactFiberExpirationTime.js文件中找到它的定义。 export type ExpirationTime = number; Expiratio

tangding12的博客 524

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

React 16.7 Fiber源码解读 (二)之运行流程

Fiber Debugger Fiber Debugger是React官方的一个图形化展示fiber运行过程的动态demo. 点击Edit按钮,可将以下代码复制到编辑框,点击运行Run即可查看 log('Render &amp;amp;amp;amp;amp;amp;amp;lt;div&amp;amp;amp;amp;amp;amp;amp;gt;Hello&amp;amp;amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;am

辰辰沉沉大辰沉 3046

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

react源码浅析(六):到期时间的计算规则

NodeNote,持续更新中react相关库源码浅析, react ts3 项目 [TOC] 到期时间的计算方法 到期时间算法源码位置: react\packages\react-reconciler\src\ReactFiberExpirationTime.js 复制代码摘要: react主要把到期时间分为两种:异步任务到期时间与交互动作的到期时间。在这之前需要了解一下一些重要的函数,reac...

weixin_33948416的博客 1218

RN,view创建过程浅析

以最基础的View组件具体,其他组件都大同小异。 node_modules/react-native/Libraries/Components/View/View.js class View extends ReactNative.NativeComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Props&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;g

少林扫地人的博客 2139

React Fiber源码分析 第二篇(同步模式)

系列文章 React Fiber源码分析 第一篇 React Fiber源码分析 第二篇(同步模式) React Fiber源码分析 第三篇(异步状态) React Fiber源码分析 第四篇(归纳总结) 前言 React Fiber是React在V16版本中的大更新,利用了闲余时间看了一些源码,做个小记录~ 如果有错误,请轻喷 流程图 流程图1 流程图2 源码分析 1.scheduleRoo...

weixin_33937499的博客 224

react16的渲染过程(源码阅读总结)

最近阅读了react16.6.0的源码,写一些心得,主要是简单描述一下reactDom.render之后发生的事情,纯粹是在说是怎么实现的,一些其他收获以后再添加。 首先会根据传入的元素调用react.createElement方法传入(类型,props,子组件)创建react元素。 之后会reactDom.render会调用createContainer方法创建fiberRoot,即根节点的...

刘鹏翔的一些分享 822

Fix signatures do not match the previously installed version

报错信息FAILURE: Build failed with an exception.* What went wrong: Execution failed for task ':app:installDebug'. > com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: Fai

Wang的专栏 2万+

在react中 实现 base64的图片转换成formdata格式并实现上传功能

如果不想要服务端实现处理base64格式的图片的转换,那么在浏览器端来实现,部分属于伪代码,仅作为开发参考,请勿直接拷贝使用

Wang的专栏 8836

快速解决gradle下载慢的问题的小技巧

在ionic run 或build 或clean命令的时候,如果没有下载过gradle, 需要重新下载一次,而通过CLI的方式下载很慢,即使科学上网后,下载还是存在一些问题。这里总结一下,快速的下载安装方式。 步骤 本地安装 http-server 包, 通过 $ npm i -g http-server 的方式安装到全局 在官网上下载自己的版本,目前自带的版本是 2.14.1,其他版本可能在执行过

Wang的专栏 6714

React 实现 2D 画板功能

在移动端或者PC端我们来模拟画板的实现, 支持清除和导出功能,此处简单实现,仅作开发参考。 效果演示 主要代码演示 /* 此模块用于实现签名绘图功能 */ // 需要用到的变量定义 let clickX = new Array(); let clickY = new Array(); let clickDrag = new Array(); let paint; let point...

Wang的专栏 4325

React16源码: React中LegacyContext的源码实现

对于在 beginWork 中的 context 操作,可以看上述判断成立的条件下的代码,即便有符合跳过更新的操作,依然 需要 push 和 pop 操作。如果我们可以跳出组件的更新,也就是代表着当前这个 classComponent,它的state它的props都应该是没有任何变化的。对于子组件来说,它的所有子树所获取到的context肯定是经过子组件,和上层的父组件合并的 context 了, 也就是。所以,先 push 一个老的值进去再说, 然后到后面,如果发现这个组件它是要更新的,就调用这个。

Wang的专栏 2803
上一篇: React16源码: React中更新阶段中不同类型的expirationTime之pendingTime,suspendedTime以及pingedTime的源码实现
下一篇: 前端架构: 脚手架在前端研发流程中的意义
Wang's Blog
博客等级 码龄12年 7434粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

Wang's Blog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值