React 中的 Fiber 架构

React Fiber 介绍

在这里插入图片描述

React Fiber 是 React 的一种重写和改进的核心算法,用于实现更细粒度的更新和高效的调度。它是 React 16 版本中的一个重要更新,使得 React 能够更好地处理复杂和高频的用户交互。以下是对 React Fiber 的详细介绍:

为什么需要 React Fiber?

在传统的 React 中,更新操作是同步的,一旦开始更新,整个组件树的更新过程不会被中断。这在处理复杂组件树或高频用户交互时,可能导致界面卡顿和响应变慢。为了解决这个问题,React Fiber 引入了更灵活的调度机制,使得 React 能够将更新任务分成更小的工作单元,并在适当的时候中断和恢复这些任务,从而提升应用的性能和用户体验。

Fiber 架构具有以下特点:

增量渲染

Fiber 将渲染工作分成多个小的工作单元,这些单元可以在多个帧中执行。由于分成了更小的任务单元,在这些任务单元之间可以停顿,可以执行其他任务。

优先级调度

不同的任务根据其重要性被赋予不同的优先级,确保用户输入等高优先级任务能够快速响应。

恢复和暂停

React 可以在处理完一个工作单元后中断,检查是否有更高优先级的任务需要处理。如果有,则优先处理高优先级任务。否则,继续处理剩余的渲染任务。

两阶段 & 两棵树

Fiber 架构包含两个阶段:

调度阶段(Reconciliation Phase)

这一阶段,React 会计算需要更新的组件和对应的状态变更。调度阶段是可以被中断的,React 会根据优先级逐步处理更新任务。

提交阶段(Commit Phase)

一旦调度阶段完成,提交阶段会将更新应用到实际的 DOM 中。提交阶段是同步的,React 会确保所有的 DOM 变更在一次帧内完成。

Fiber架构在内存中包含了两棵树,一棵是当前树已经渲染完成的树,也就是已经展现在页面上的。一棵是工作树(Work-in-Progress Tree),这两棵树互相替换进行状态的更新。

克隆和更新:

当发生更新(例如,状态变化或新的 props)时,React 通过克隆当前树创建一棵进行中工作树。当前树中的每个节点都会被复制到进行中工作树中。
然后,React 在工作树上执行差异分析,这涉及调用组件的 render 方法,将生成的元素与以前的元素进行比较,并在需要时生成新的进行中工作 fiber。

提交阶段:

一旦进行中工作树完全调和并计算了所有更新,React 进入提交阶段。在提交阶段,工作树中的更改会应用到 DOM 中,工作树成为新的当前树。这是一个原子操作,确保 UI 一致地更新。

双缓冲:

React Fiber 使用类似于计算机图形学中的双缓冲的概念。通过在单独的副本(工作树)上工作,React 可以在屏幕外计算更新,然后快速将其应用到屏幕上,最大限度地减少 UI 处于不一致状态的时间。

Fiber 节点对象

在这里插入图片描述

Fiber节点主要包含以下属性,完整代码,移步至 React 源码,Fiber节点是 React 的核心,Fiber 节点保存着和节点相关的所有重要信息。不同 ReactElement,每次都创建新的,Fiber 节点是从用的这也就是为什么函数式组件可以有状态的原因。

{
  // 组件或 DOM 节点的类型(例如:"div", "App", "Button")
  type: 'div',

  // 关联的 DOM 节点(如果适用)
  stateNode: document.createElement('div'),

  // 当前 fiber(表示该组件的最新 fiber)
  // 用于在下一个调和阶段检查此 fiber 是否已更新
  return: null,
  child: null,
  sibling: null,
  index: 0,

  // 备用 fiber(表示该组件的上一个 fiber)
  // 用于在下一个提交阶段对 DOM 执行副作用和清理操作
  // 这仅用于非并发模式
  alternate: null,

  // 备忘的 props 和 state(该组件的最新 props 和 state)
  // 用于在下一个调和阶段检查组件是否需要更新
  memoizedProps: {},
  memoizedState: {},

  // 过期时间(该组件需要更新的截止时间)
  // 用于在下一个阶段优先更新哪些组件
  expirationTime: 0,
}

工作的单元划分

在 Fiber中,任务被划分成了工作单元,根据优先级进行调度,优先级高的先执行。Fiber中,通过 WorkLoop 执行 Fiber树上的节点,每次执行前会检查是否需要释放给更高优先级的任务,相当于暂停的操作。WokLoop 源代码

function workLoopConcurrent() {
  // Perform work until Scheduler asks us to yield
  while (workInProgress !== null && !shouldYield()) {
    // $FlowFixMe[incompatible-call] found when upgrading Flow
    performUnitOfWork(workInProgress);
  }
}

执行任务,任务具体的执行是在 beginWork 和 completeUnitOfWork 中,beginWork中处理 Fiber节点的主要逻辑,completeUnitOfWork主要是收尾工作。

function performUnitOfWork(unitOfWork: Fiber): void {
  // The current, flushed, state of this fiber is the alternate. Ideally
  // nothing should rely on this, but relying on it here means that we don't
  // need an additional field on the work in progress.
  const current = unitOfWork.alternate;
  setCurrentDebugFiberInDEV(unitOfWork);

  let next;
  if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
    startProfilerTimer(unitOfWork);
    next = beginWork(current, unitOfWork, renderLanes);
    stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
  } else {
    next = beginWork(current, unitOfWork, renderLanes);
  }

  resetCurrentDebugFiberInDEV();
  unitOfWork.memoizedProps = unitOfWork.pendingProps;
  if (next === null) {
    // If this doesn't spawn new work, complete the current work.
    completeUnitOfWork(unitOfWork);
  } else {
    workInProgress = next;
  }

  ReactCurrentOwner.current = null;
}

总结

React Fiber 是 React 渲染的重要概念,可以说 React 主要数据都是保存在 Fiber 树上,对状态的改动最终都会体现在 Fiber 节点的更新上。随着前端页面的复杂度的升高,对于渲染效率的要求也越来越高,Fiber 这种将渲染任务进行切分的设计理念大大提高了复杂前端单页面应用的用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/659155.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

便民社区信息小程序源码系统 功能强大 带生活电商+求职招聘功能 带完整的安装代码包以及搭建教程

系统概述 便民社区信息小程序源码系统是一款集多种功能于一身的综合性平台。它旨在为用户提供便捷的生活服务,满足社区居民的各种需求。无论是购物、求职还是获取社区信息,都能在这个平台上得到满足。该系统采用先进的技术架构,确保系统的稳…

【python 进阶】 绘图

1. 将多个柱状绘制在一个图中 import seaborn as sns import matplotlib.pyplot as plt import numpy as np import pandas as pd# 创建示例数据 categories [A, B, C, D, E] values1 np.random.randint(1, 10, sizelen(categories)) values2 np.random.randint(1, 10, siz…

揭秘!编写高质量代码的关键:码农必知的黄金法则!

文章目录 一、保持代码的简洁与清晰二、遵循良好的命名规范三、注重代码的可读性四、利用抽象与封装五、遵循SOLID原则六、关注代码性能七、确保代码安全性《码农修行:编写优雅代码的32条法则》编辑推荐内容简介目录前言/序言 在编程的世界里,每一位码农…

VSCode 报错 之 运行 js 文件报错 ReferenceError: document is not defined

1. 背景 持续学习ing 2. 遇到的问题 在VSCode 右键 code runner js 文件报错 ReferenceError: document is not defined eg: // 为每个按钮添加点击事件监听器 document.querySelectorAll(button).forEach(function (button) {button.addEventListener(click, f…

python基础-数据结构-leetcode刷题必看-heapq --- 堆队列算法

文章目录 堆的定义堆的主要操作堆的构建堆排序heapq模块heapq.heappush(heap, item)heapq.heappop(heap)heapq.heappushpop(heap, item)heapq.heapreplace(heap, item)heapq.merge(*iterables, keyNone, reverseFalse)heapq.nlargest(n, iterable, keyNone)heapq.nsmallest(n, …

赛氪网与武汉外语外事职业学院签署校企合作,共创职业教育新篇章

5月23日下午14:00,武汉外语外事职业学院在藏龙岛校区食堂三楼报告厅隆重举行了2024年职业教育活动周优秀校外实习基地表彰仪式。本次活动旨在表彰在职业教育领域作出突出贡献的校外实习基地,同时加强校企合作,共同推动职业教育的发展。作为重…

gitlab之docker-compose汉化离线安装

目录 概述离线资源docker-compose结束 概述 gitlab可以去 hub 上拉取最新版本,在此我选择汉化 gitlab ,版本 11.x 离线资源 想自制离线安装镜像,请稳步参考 docker镜像的导入导出 ,无兴趣的直接使用在此提供离线资源 百度网盘(链…

经典文献阅读之--RepViT-SAM(利用语义分割提高NDT地图压缩和描述能力的框架)

0. 简介 Segment Anything Model (SAM) 最近在各种计算机视觉任务上展现了令人瞩目的零样本迁移性能 。然而,其高昂的计算成本对于实际应用仍然具有挑战性。MobileSAM 提出通过使用蒸馏替换 SAM 中的重图像编码器,使用 TinyViT,从而显著降低了…

认识K8s集群的声明式资源管理方法

前言 Kubernetes 集群的声明式资源管理方法是当今云原生领域中的核心概念之一,使得容器化应用程序的部署和管理变得更加高效和可靠。本文将认识了解 Kubernetes 中声明式管理的相关理念、实际应用以及优势。 目录 一、管理方法介绍 1. 概述 2. 语法格式 2.1 管…

AI图书推荐:用ChatGPT和Python搭建AI应用来变现

《用ChatGPT和Python搭建AI应用来变现》(Building AI Applications with ChatGPT API)将ChatGPT API与Python结合使用,可以开启构建非凡AI应用的大门。通过利用这些API,你可以专注于应用逻辑和用户体验,而ChatGPT强大的…

适合学生党的蓝牙耳机有哪些?盘点四大性价比蓝牙耳机品牌

对于追求高品质音乐体验而又预算有限的学生党来说,一款性价比高的蓝牙耳机无疑是最佳选择,在众多品牌和型号中,如何挑选到既适合自己需求又价格亲民的蓝牙耳机,确实是一个值得思考的问题,作为一个蓝牙耳机大户&#xf…

台灯护眼是真的吗?警惕这六大问题!

在当今社会,随着电子设备的普及和长时间的用眼,大多数人面临着严重的视觉疲劳问题。长时间盯着屏幕或学习,眼睛需要不断调节焦距,导致眼睛肌肉疲劳,进而引发视力下降。这种现象在年轻一代甚至青少年中尤为普遍&#xf…

半导体测试基础 - 功能测试

功能测试(Functional Test)主要是验证逻辑功能,是运用测试矢量和测试命令来进行的一种测试,相比于纯 DC 测试而言,组合步骤相对复杂且耦合度高。 在功能测试阶段时,测试系统会以周期为单位,将测试矢量输入 DUT,提供预测的结果并与输出的数据相比较,如果实际的结果与测…

图论(五)-最短路

一、Bellman-Ford算法 算法思想:通过 n 次循环,每次循环都遍历每条边(共 m 条边),进而更新节点的距离,每次循环至少可以确定一个点的最短路,循环 n 次,求出 n 个点的最短路 时间复杂…

opencascade V3d_RectangularGrid 源码学习

类V3d_RectangularGrid V3d_RectangularGrid() V3d_RectangularGrid::V3d_RectangularGrid(const V3d_ViewerPointer &aViewer, const Quantity_Color &aColor, const Quantity_Color &aTenthColor) // 构造函数 ◆ ~V3d_RectangularGrid() virtual V3d_Rectang…

YOLOv10最详细全面讲解1- 目标检测-准备自己的数据集(YOLOv5,YOLOv8均适用)

YOLOv10没想到出来的如此之快,作为一名YOLO的爱好者,以YOLOv5和YOLOv8的经验,打算出一套从数据集装备->环境配置->训练->验证->目标追踪全系列教程。请大家多多点赞和收藏!!!YOLOv5和YOLOv8亲测…

Simulink从0搭建模型06-P7模型中结构体的使用

Simulink从0搭建模型06-P7模型中结构体的使用 本节课学习内容1. 结构体的创建 Bus Creator(多输入单输出)2. 结构体的引用 Bus Selector(单输入多输出)3. 结构体的赋值 Bus Assignment4. 结构体对象的创建 Bus object5. 结构体数组…

10分钟掌握FL Studio21中文版,音乐制作更高效!

FL Studio 21中文版是Image Line公司推出的一款深受欢迎的数字音频工作站软件,在音乐制作领域享有盛誉。这个版本特别针对中文用户进行了本地化处理,旨在提供更加便捷的用户体验和操作界面。本次评测将深入探讨FL Studio 21中文版的功能特点、使用体验及…

Java RMI

RMI - 安全篇 RMI分为三个主体部分: *Client-客户端*:客户端调用服务端的方法 *Server-服务端*:远程调用方法对象的提供者,也是代码真正执行的地方,执行结束会返回给客户端一个方法执行的结果。 *Registry-注册中心…

防火墙技术基础篇:配置主备备份的双机热备

防火墙技术基础篇:配置主备备份的双机热备 防火墙双机热备(High Availability, HA)技术是网络安全中的一个关键组成部分,通过它,我们可以确保网络环境的高可靠性和高可用性。下面我们一起来了解防火墙双机热备的基本原…