React源码之Fiber架构

前端宝典之三:React源码解析之Fiber架构 本文主要内容: 1、React Concurrent 2、React15架构 3、React16架构 4、Fiber架构 5、任务调度循环和fiber构造循环区别 阅读详情

什么是Fiber?

Fiber又命为纤程,他是与进程、线程、协程同为操作系统中程序的执行过程,可以将纤程理解为操作系统中的协程,那么generator也可以理解为协程,为什么没有使用generator来作为协程呢?
在这里插入图片描述

  • 当使用generator与async与await一样也是有传染性的,需要不断向上面声明*或者类似async与await中的async。
  • 实现更新可以中断并继续,实现更新可以拥有不同的优先级,高优先级的更新可以打断低优先级的更新,使用generator可以达到第一个目的,但是无法实现高优先级的更新可以打断低优先级的更新。

两种定义

静态数据结构

对于Fiber也作为一个静态数据结构,对于着一个组件保存了该组件的类型和对应的Dom节点等信息,这个时候的Fiber节点也就是我们所说的虚拟Dom。
在一个页面中可以有多个RootFiber,但是需要有一个FiberRootNode来管理这些RootFiber。

动态工作单元

每个 Fiber 节点保存了本次更新中该组件改变的状态、要执行的工作(需要被删除、被插入页面中、被更新…)。
对于Fiber我们可以理解为存储在内存中的Dom,在React15的协调器(Reconciler)是通过递归调用执行栈来实现的,在React16中的协调器(Reconciler)是基于Fiber节点来实现的。
对于React15在render阶段的reconcile是不可打断的,如果在操作大量的dom时,会存在卡顿,因为浏览器将所有的时间都交给了js引擎线程去执行,此时GUI渲染线程被阻塞,导致页面出现卡顿,无法响应用户对应的事件。
所以在React16之后就有了Scheduler来进行时间片的调度,给每一个task一定的时间,如果在这个时间内没有执行完,也要交出执行权给浏览器进行绘制和重排,所以异步可中断的更新需要一定的数据结构在内存中保存dom信息,所以产出了这样一种数据结构Fiber,也可以称为虚拟Dom。

Fiber数据结构

function FiberNode(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
  ) {
    // Instance
    // tag是Fiber对应的组件类型,比如Funtion Component、Class Component、Hooks Component
    // 其中Hooks Component是指Dom节点对应的Fiber节点
    this.tag = tag;
    this.key = key;
    // elementType大部分情况与type相同,除非Function Component使用React.memo来包裹时,他的ElementType与type不同
    // type对于Funtion Component来说是函数本身,对于Class Component是Class,对于Hooks Component是Dom节点的TagName
    this.elementType = null;
    this.type = null;
    // stateNode对于Hooks Components来说指对应的真实Dom节点
    this.stateNode = null;
    
    // Fiber
    // return/child/sibling会链接储存一颗Fiber树
    this.return = null;
    this.child = null;
    this.sibling = null;
    // 对于多个同级的Fiber节点,代表插入Dom的位置索引
    this.index = 0;
    // 就是我们常用的Ref属性
    this.ref = null;
    
    // 下面的属性都是将Fiber作为动态的工作单元使用时的属性 
    this.pendingProps = pendingProps;
    this.memoizedProps = null;
    this.updateQueue = null;
    this.memoizedState = null;
    this.dependencies = null;
    
    this.mode = mode;
    
    // Effects
    this.flags = NoFlags;
    this.subtreeFlags = NoFlags;
    this.deletions = null;
    
    // 调度优先级
    this.lanes = NoLanes;
    this.childLanes = NoLanes;
    // 关系到Fiber架构的工作方式
    this.alternate = null;
    
    if (enableProfilerTimer) {
      // Note: The following is done to avoid a v8 performance cliff.
      //
      // Initializing the fields below to smis and later updating them with
      // double values will cause Fibers to end up having separate shapes.
      // This behavior/bug has something to do with Object.preventExtension().
      // Fortunately this only impacts DEV builds.
      // Unfortunately it makes React unusably slow for some applications.
      // To work around this, initialize the fields below with doubles.
      //
      // Learn more about this here:
      // https://github.com/facebook/react/issues/14365
      // https://bugs.chromium.org/p/v8/issues/detail?id=8538
      this.actualDuration = Number.NaN;
      this.actualStartTime = Number.NaN;
      this.selfBaseDuration = Number.NaN;
      this.treeBaseDuration = Number.NaN;
    
      // It's okay to replace the initial doubles with smis after initialization.
      // This won't trigger the performance cliff mentioned above,
      // and it simplifies other profiler code (including DevTools).
      this.actualDuration = 0;
      this.actualStartTime = -1;
      this.selfBaseDuration = 0;
      this.treeBaseDuration = 0;
    }
    
    if (__DEV__) {
      // This isn't directly used but is handy for debugging internals:
    
      this._debugSource = null;
      this._debugOwner = null;
      this._debugNeedsRemount = false;
      this._debugHookTypes = null;
      if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
        Object.preventExtensions(this);
      }
    }
}

Fiber双缓存

什么是双缓存呢?我们可以由动画来举例
动画由多张连续的图片组成,每一张图可以成为动画的一帧,当我们播放动画时需要有一定的速度连续展示每一帧,在渲染新的一帧的图片时需要将前一帧的图片清除,如果从清除前一帧图片到下一帧之间所展示的图片过长就会出现人眼能够感知的白屏闪烁,为了解决这个问题,我们可以从内存中绘制当前帧的图片,绘制完毕后直接用当前帧去替换掉上一帧的图片,由于这两帧替换出来所消耗的时间不会出现从白屏到画面闪烁的情况(速度足够快),这种在内存中构建并直接替换的技术称之为双缓存。
举例:
对于这样的Dom结构会生成如下的Fiber

function App() {
  return (
    <div>
      zi
      <p>bai</p>
    </div>
  )
}
ReactDOM.render(<App />, document.getElementById("root"));

对于上述结构的Fiber图如下:
在这里插入图片描述

mount

对于前面对于Fiber定义的讲解,我们知道了Fiber作为虚拟Dom可以保存和描述真实的dom,在mount的时候会先将jsx对象构建Fiber对象,形成Fiber树,这颗Fiber树叫做current Fiber并对应到真实Dom上。而正在构建的Fiber树叫做workInProgress Fiber,两棵树的节点会通过alternate相连。
对于首次进入页面的渲染时会通过ReactDom.Render来创建FiberRootNode,对于fiberRoot是指整个应用的根节点,只存在一个。每次调用ReactDom.Render都会创建当前应用的根节点RootFiber,对于rootFiber是指ReactDom.render或者ReactDOM.unstable_createRoot所创建出来的节点,可以存在多个其中会有一个current指针来指向RootFiber节点,由于在首屏渲染之前页面是空白的所以RootFiber没有子节点,接下来无论是首屏渲染还是调用this.setState或者调用useState的Hooks方法来创建的更新都会从根节点来开始创建一颗Fiber树。
在Mount时候只会创建FiberRootNode和rootFiber两个节点。初始时如下:
在这里插入图片描述
然后根据jsx创建workInProgress Fiber,然后通过alternate链接
在这里插入图片描述
接着workInProgress Fiber会和current Fiber交换位置,此时workInProgress变为current Fiber并渲染成对应的真实Dom则为如下图:
在这里插入图片描述

update

对于更新来讲,我们可以理解为动画帧,双缓存的替换类比为动画的两帧,当动画的下一帧替换动画的上一帧的速度够快就不会出现卡顿现象。此时我们来类比为Fiber,当更新时会在内存中生成workInProgress,然后将workInProgress替换为current Fiber并将current指针指向workInProgress Fiber并渲染为对应的Dom,如果执行速度够快就不会出现卡顿的现象。具体过程如下:
在update时会根据current Fiber与状态变更后的jsx对象做对比形成新的workInProgress Fiber,其过程也就是diff算法,然后workInProgress Fiber切换成current Fiber应用到真实dom就达到了更新的目的,这一切都是在内存中发生的,减少了对dom的操作。
在这里插入图片描述
最后再把workInProgress Fiber切换为current Fiber
在这里插入图片描述
上述为update时,current Fiber与workInProgress Fiber的变化

React 调和(Reconciler)原理理解 文章目录FiberFiber 更新机制 Fiber Reactv15及之前,React 对于虚拟 DOM 是采用 递归方式 遍历更新的,一次更新,从应用根部递归更新,递归开始后中途无法终端,随着项目复杂,层级变深,导致更新时间变成,给前端交互上的体验就卡顿。 Fiber 诞生在 Reactv16 版本,Fiber 架构目的就是解决大型 React 应用卡顿,fiber 在 React 中是最小粒度的执行单元,在遍历更新每一个节点的时候都不是用的真实 DOM ,都是采用虚拟 DOM ,所以可以 理解成 f 阅读详情

相关推荐

React源码分析2-深入理解fiber

本章讲解了 fiber 出现的主要原因、fiber 节点中主要的属性以及 fiber 树是如何构建与更新的。

It_kc的博客 538

万字长文介绍React Fiber架构的原理和工作模式

这篇文章从React Fiber架构的原理和源码入手,为你织开一面关于Fiber架构的基础知识网络。

BigYe_ChengPu的博客 2385

【React源码 - Fiber架构之Reconciler】

React源码-Fiber架构之Reconciler

weixin_44273311的博客 2124

react fiber架构【详细讲解,看这一篇就够了】

React Fiber 架构首次在 React v16.0 中引入,这是在2017年9月26日发布的。该版本的发布标志着 React Fiber 架构的正式推出,为 React 应用程序的性能和交互体验带来了重大改进。React Fiber 架构的引入使得 React 应用程序更具灵活性和可扩展性,能够更好地处理大型应用程序的渲染和交互需求。react filber解决了什么问题。

努力的鋜 2827

【React源码 - Fiber架构之Renderer】

React源码-Fiber架构之Renderer

weixin_44273311的博客 1712

Perplexity AI 高效使用培训手册

Perplexity AI 是一款革命性的 AI 搜索引擎,提供免费版和专业版两种选择。免费版支持基础搜索、每日3次Pro搜索、3个文件上传和初步深度研究功能;Pro版则解锁无限次Pro搜索、无限制文件上传、AI图像生成等高级功能,适合专业用户深度研究。该工具能整合网络信息、分析本地文档、生成创意内容,并提供知识库管理功能,显著提升信息检索和内容创作效率。用户可根据需求选择合适版本,免费版已能满足日常使用,而Pro版则更适合专业场景。

conquer_qgw的博客 1208

【React源码03】深入学习React 源码实现——Fiber 架构与任务调度

React Fiber 架构深度解析:从源码看高性能渲染机制 React Fiber 架构通过任务拆分与优先级调度彻底改变了渲染机制。核心创新包括: 链表结构的Fiber节点设计,支持中断恢复 双缓冲机制实现无闪烁更新 基于Lane模型的优先级系统(32位掩码) 可中断的工作循环(workLoopConcurrent) 时间切片技术(shouldYield判断) 关键源码集中在react-reconciler包,通过Fiber节点间的return/child/sibling指针构建虚拟树等。

silverclayz的技术分享 1741

BIOS更新后PIN不可用怎么办?从原理到实操的完整修复指南

在计算机维护中,BIOS更新是常见的固件升级操作,但其引发的登录异常却常让用户措手不及。Windows Hello PIN并非传统密码,它通过TPM芯片与设备启动环境(PCR状态)强绑定,一旦主板固件或安全启动配置改变,TPM便会拒绝释放密钥,导致“由于此设备上的更改,你的PIN不再可用”。理解这一原理后,恢复路径清晰可控:优先尝试密码登录,或通过WinRE替换utilman.exe创建临时管理员,必要时还需处理BitLocker恢复密钥。本文面向系统维护与数据安全场景,系统梳理PIN失效的恢复流程与避坑方

weixin_31364787的博客 383

React Fiber架构及源码解析

背景与起源:React Fiber是React 16引入的重新实现的协调算法,旨在解决旧版本中渲染阻塞问题。核心目标:实现增量渲染、任务分片和优先级调度,提升复杂应用的性能与用户体验。基本概念:协调(Reconciliation)、虚拟DOM、双缓冲技术等。架构影响:Fiber使React从同步更新模型演进为异步可中断模型。未来方向:与并发模式、服务器组件等新特性的关系。实践建议:如何利用Fiber特性优化应用性能。

weixin_45142660的博客 711

三极管NPN与PNP的工作原理及快速识别技巧

本文深入浅出地解析了三极管NPN与PNP的核心工作原理。通过“水龙头”比喻,阐明其以小电流控制大电流的放大与开关本质。文章重点对比了NPN与PNP在电流方向、电位关系和控制逻辑上的根本区别,并提供了快速识别技巧与实用的选型、应用指南,帮助电子爱好者与工程师快速掌握这两种基础元件的关键知识。

neovim7hacker的博客 456

蓝牙Channel Sounding为真正的距离感知赋能

1:工作原理蓝牙™信道探测使用两种经过验证的测距方法——PBR(PBR)和RTT(RTT),实现蓝牙设备之间的安全精密测距。

weixin_43720159的博客 809

react源码中的fiber架构

这一章讲述了整个的fiber架构与fiber树的创建与更新,那么这里从React应用的初始化挂载到React更新就形成了一部分的闭环完结,之后我们便是沿着流程走到了更新这里。

weixin_59558923的博客 560

Jetson Nano官方镜像下载&烧录

在NVIDIA Jetson Nano开发者套件上安装NVIDIA官方Ubuntu镜像

weixin_44222088的博客 8854

【React源码09】深入学习React 源码实现——Fiber架构副作用收集Effect List

React Fiber架构通过副作用收集机制实现了高效更新。在协调阶段(render phase),React遍历Fiber树并标记需要执行的DOM操作(如插入、更新、删除),将这些副作用收集到effectList中。在提交阶段(commit phase),React批量执行这些副作用到真实DOM。这种机制使React能够灵活调度任务,支持并发特性,同时保持高效的更新性能。

silverclayz的技术分享 1304

实战指南:从零搭建ROS2 + Cartographer 2D激光SLAM系统

本文详细介绍了如何从零开始搭建ROS2与Cartographer结合的2D激光SLAM系统,涵盖环境准备、激光雷达驱动配置、Cartographer安装与参数调优等关键步骤。通过实战案例和常见问题解决方案,帮助开发者快速掌握激光雷达建图技术,提升机器人自主导航能力。

weixin_29062255的博客 404

【RF】Receiver Function接收函数:从理论到实践的深度解析

本文深入解析地震学中的接收函数(Receiver Function, RF)技术,从理论原理到实践操作。文章将RF比作地球的“听诊器”,详细阐述了其通过反褶积剥离震源影响、揭示地下结构(如莫霍面)的核心机制,并提供了使用Python和rf库进行数据处理、计算、动校正与叠加的完整实战流程,同时探讨了其应用、局限性与常见问题的解决方案。

Jerry的专栏 122

React16源码之React Fiber架构

原文地址:github.com/HuJiaoHJ/bl… 本文源码是2018年8月10日拉取的React仓库master分支上的代码 React源码分析内容非常多,本文专注在以下两个问题: JSX -&gt; ? -&gt; DOM React Component 的生命周期函数是怎么被调用的? 在开始源码分析之前,首先先简单介绍一下React的一些基础概念 基础概念 React定位是一个...

weixin_34324081的博客 365

vLLM显存逆向计算:如何得到最优gpu-memory-utilization参数

本文提出了一种**逆向工程**的思路:基于vLLM显存占用的底层机制,通过精确计算模型权重、KV缓存、激活内存等各组件的显存需求,**倒推出最优的gpu-memory-utilization参数**。这种方法让我们能够在部署前就准确预估资源需求,实现一次配置、稳定运行。本文我们将从vLLM显存计算的核心原理出发,构建完整的倒推计算框架和源码,并通过大量实验验证其准确性(会有误差,但基本可以直接使用)。

羊城迷鹿的博客 1952

【React源码08】深入学习React 源码实现——Fiber架构双缓冲(current 与 workInProgress)机制

React的双缓冲机制(current与workInProgress)是Fiber架构的核心特性,通过两棵Fiber树的交替使用实现高效的UI更新。在更新过程中,React基于current树创建workInProgress树,所有更新操作在workInProgress树上进行,完成后通过commitRoot提交并切换指针。这种机制允许React保留当前状态,并支持中断/恢复渲染。源码中createWorkInProgress函数负责节点的创建/复用,通过alternate指针实现双树快速切换。

silverclayz的技术分享 944

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

react源码解析7.Fiber架构

react源码解析7.Fiber架构 视频讲解(高效学习):进入学习 往期文章: 1.开篇介绍和面试题 2.react的设计理念 3.react源码架构 4.源码目录结构和调试 5.jsx&核心api 6.legacy和concurrent模式入口函数 7.Fiber架构 8.render阶段 9.diff算法 10.commit阶段 11.生命周期 12.状态更新流程 13.hooks源码 14.手写hooks 15.scheduler&Lane 16.concurrent模式 17.co

weixin_59558923的博客 188

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

上一篇: React源码之概念篇
下一篇: React源码之render过程中发生了什么?
我的名字豌豆
博客等级 码龄7年 157粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值