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

本文主要是介绍React16源码: React中的resetChildExpirationTime的源码实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

resetChildExpirationTime


1 )概述

  • completeUnitOfWork 当中,有一步比较重要的一个操作,就是重置 childExpirationTime
  • childExpirationTime 是非常重要的一个时间节点,它用来记录某一个节点的子树当中,目前优先级最高的那个更新
  • 整个应用的调度过程当中使用的都是root节点,在 scheduleWork 的时候,即便我们创建更新的那个节点,是我们写的某一个组件
  • 但最终要先找到那一个root节点,然后再把它放到调度队列当中,因为会有这样的一个情况的存在
  • 所以我们对于一个 reactApp 来说,它某一个节点下面可能是会存在非常多的一个子树的
  • 每棵子树它创建的不同的任务,它的 expirationTime 都会不一样的
  • 通过 childExpirationTime 来集中,最终可以在 root 上面能够快速的找到整个应用当中优先级最高的那个任务
  • 举个例子,假设同时在 Input 和 List 两个组件内都去创建了一个异步的更新,创建这个异步的更新的过程当中
  • 假设,Input的 ExpirationTime 优先级比较高,List 的 expirationTime 优先级比较少
  • 对于div节点来说,它记录的是Input节点的 expirationTime, 因为它的优先级比较高
  • 对于div来说,它如果下一个任务要去更新,它的优先级肯定是先更新 Input,而不会先更新 List
  • 对于 RootFiber 和 App来说,因为它们的child只有div, 所以它们记录的会是 div 上面指定的那个优先级最高的 expirationTime
  • 所以说 childExpirationTime 对于有分叉的点来说是非常重要的, 它可以记录不同的子树所创建的不同的更新
  • 如果我们的分叉变得越来越多,有非常多个的时候,那么用这种方式来记录它的效率明显是会是更高一点的
  • 对于这个情况下,如果我 Input 这个更新已经执行完了,它上面已经没有 expirationTime,因为它没有任务要去更新了
  • 对于div来说,这个时候如果它还是认为这个Input它之前的 expirationTime 是最高优先级的话,那就不对了,之后的更新可能就会有出现问题
  • 所以对于div这个节点,我们执行了 completeUnitOfWork 之后,要去更新它的 childExpirationTime
  • 对于每一个节点都是一样的, 在上述这个例子里面,特别重要的一点就是 div, div 要更新,那么它上面的节点都是要更新的
  • 因为它们之前记录的都是 div 记录的那个值,所以,它们执行 completeUnitOfWork 的时候,也都要去做相同的操作

2 )源码

定位到 packages/react-reconciler/src/ReactFiberScheduler.js#L989

对应到代码里面,来看在 completeUnitOfWork 里面,我们这边执行完了 completeWork
马上会执行 resetChildExpirationTime 那么这个方法它具体做了什么呢?

function resetChildExpirationTime(workInProgress: Fiber,renderTime: ExpirationTime,
) {// 首先判断 renderTime ,就是当前正在执行更新的那一个优先级对应的 expirationTime// 如果它不等于never,并且 workInProgress.childExpirationTime 等于 Never// 也就是说 workInProgress 就是我们当前节点的子节点优先级最高的那个任务是never// 就是永远不会更新到的并且我们现在也不是正在执行,never,就是永远不会更新到的那些节点的更新// 说明我们这边根本就不需要做任何的操作,所以我们直接return就可以了if (renderTime !== Never && workInProgress.childExpirationTime === Never) {// The children of this component are hidden. Don't bubble their// expiration times.return;}let newChildExpirationTime = NoWork;// Bubble up the earliest expiration time.// 跳过这个if, 直接到 elseif (enableProfilerTimer && workInProgress.mode & ProfileMode) {// We're in profiling mode.// Let's use this same traversal to update the render durations.let actualDuration = workInProgress.actualDuration;let treeBaseDuration = workInProgress.selfBaseDuration;// When a fiber is cloned, its actualDuration is reset to 0.// This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).// When work is done, it should bubble to the parent's actualDuration.// If the fiber has not been cloned though, (meaning no work was done),// Then this value will reflect the amount of time spent working on a previous render.// In that case it should not bubble.// We determine whether it was cloned by comparing the child pointer.const shouldBubbleActualDurations =workInProgress.alternate === null ||workInProgress.child !== workInProgress.alternate.child;let child = workInProgress.child;while (child !== null) {const childUpdateExpirationTime = child.expirationTime;const childChildExpirationTime = child.childExpirationTime;if (childUpdateExpirationTime > newChildExpirationTime) {newChildExpirationTime = childUpdateExpirationTime;}if (childChildExpirationTime > newChildExpirationTime) {newChildExpirationTime = childChildExpirationTime;}if (shouldBubbleActualDurations) {actualDuration += child.actualDuration;}treeBaseDuration += child.treeBaseDuration;child = child.sibling;}workInProgress.actualDuration = actualDuration;workInProgress.treeBaseDuration = treeBaseDuration;} else {// 这边主要是有一个 while循环, 这个while循环它首先使用的是 workInProgress.child// 它就是我们当前节点的child,然后获取child的 expirationTime 以及 childChildExpirationTime// child.expirationTime 是它自身它所创建的更新对应的 expirationTime// 而 child.childExpirationTime 是child的子树里面任何几个节点它所创建的更新所对应的优先级最高的 expirationTimelet child = workInProgress.child;while (child !== null) {// 为什么这边要用这两个值?因为我们没有办法直接拿到当前节点它所有子树最高优先级的点// 只能是通过去遍历它的所有的第一层的子节点以及每个子节点它的 childExpirationTime// 因为我们这个 completeUnitOfWork 是由底往上去更新的一个过程// 那么由底往上更新的过程,就会每一个节点都会对应这个操作// 对应的这个操作之后,它肯定就是每一个节点都会更新到优先级最高的那个 expirationTimeconst childUpdateExpirationTime = child.expirationTime;const childChildExpirationTime = child.childExpirationTime;// 接下来进行判断更新if (childUpdateExpirationTime > newChildExpirationTime) {newChildExpirationTime = childUpdateExpirationTime;}if (childChildExpirationTime > newChildExpirationTime) {newChildExpirationTime = childChildExpirationTime;}// 下一个节点child = child.sibling;}}workInProgress.childExpirationTime = newChildExpirationTime;
}
  • 以上注释写在代码里,简单来说
    • 就是在每一次 complete 一个节点之后就要
    • 去重设它的 childExpirationTime 的一个过程

这篇关于React16源码: React中的resetChildExpirationTime的源码实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/634999

相关文章

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

全面解析HTML5中Checkbox标签

《全面解析HTML5中Checkbox标签》Checkbox是HTML5中非常重要的表单元素之一,通过合理使用其属性和样式自定义方法,可以为用户提供丰富多样的交互体验,这篇文章给大家介绍HTML5中C... 在html5中,Checkbox(复选框)是一种常用的表单元素,允许用户在一组选项中选择多个项目。本

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程