React理念——Fiber架构的主要原理
React理念——Fiber架构的主要原理
- React 理念
- CPU 的瓶颈
- IO 的瓶颈
- Fiber的产生及原理
- 如何构建副作用链表
React 理念
从官网看到React的理念:
React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方式。它在 Facebook 和 Instagram 上表现优秀。
可见,关键是实现快速响应。那么制约快速响应的因素是什么呢?
我们日常使用 App,浏览网页时,有两类场景会制约快速响应:
-
当遇到大计算量的操作或者设备性能不足使页面掉帧,导致卡顿。
-
发送网络请求后,由于需要等待数据返回才能进一步操作导致不能快速响应。
这两类场景可以概括为:
-
CPU 的瓶颈
-
IO 的瓶颈(网络延迟)
CPU 的瓶颈
当项目变得庞大、组件数量繁多时,就容易遇到 CPU 的瓶颈。
主流浏览器刷新频率为 60Hz,即每(1000ms / 60Hz)16.6ms 浏览器刷新一次。
我们知道,JS 可以操作 DOM,GUI渲染线程与JS线程是互斥的。所以JS 脚本执行和浏览器布局、绘制不能同时执行。
在每 16.6ms 时间内,需要完成如下工作:
JS脚本执行 ----- 样式布局 ----- 样式绘制
当 JS 执行时间过长,超出了 16.6ms,这次刷新就没有时间执行样式布局和样式绘制了。从而引起页面掉帧,造成卡顿。
如何解决这个问题呢?
答案是:在浏览器每一帧的时间中,预留一些时间给 JS 线程,React利用这部分时间更新组件(可以看到,在源码中,预留的初始时间是 5ms)。这样浏览器就有剩余时间执行样式布局和样式绘制,减少掉帧的可能性。
当预留的时间不够用时,React将线程控制权交还给浏览器使其有时间渲染 UI,React则等待下一帧时间到来继续被中断的工作。
这种将长任务分拆到每一帧中,像蚂蚁搬家一样一次执行一小段任务的操作,被称为时间切片(time slice)
解决CPU瓶颈的关键是实现时间切片,而时间切片的关键是:将同步的更新变为可中断的异步更新。
IO 的瓶颈
网络延迟是前端开发者无法解决的。只能在网络延迟客观存在的情况下,减少用户对网络延迟的感知。
Fiber的产生及原理
React Fiber 是 React 16 中引入的一种新的协调机制(协程和双缓冲技术),用于实现增量式、可中断和可恢复的异步更新方式,以提高 React 应用的性能和用户体验。
在传统的 React (React15及以前)渲染过程中,当进行组件的更新时,React 会从组件树的根节点开始递归遍历,计算出整个应用的新状态,并生成新的虚拟 DOM 树,最后将新旧虚拟 DOM 树进行对比,找出差异并进行更新。这个过程是同步的,一旦开始就无法中断,直到完成整个更新过程。如果组件树的层级很深,递归会占用线程很多时间,造成卡顿。
而 Fiber 的目标是将渲染过程拆分为多个可中断的小任务(fiber),并使用优先级调度算法决定任务的执行顺序,使得浏览器在空闲时间内可以执行其他任务或响应用户交互。这种增量式的更新方式使得 React 应用更加响应快速,避免了长时间的阻塞。
在渲染过程中根据优先级和时间片(Time Slicing)等策略,将任务分配到不同的时间片段中执行,而不是一次性将整个渲染过程执行完毕。
具体实现上,React Fiber 使用了一个双缓存技术。在任务执行过程中,React 会构建 Fiber 树,并使用两个链表结构分别表示当前任务的工作单元和下一次任务的工作单元。当时间片用尽或遇到优先级更高的任务时,React 可以中断当前任务,并将它保存到下一次任务的链表中。然后,React 可以恢复执行下一个任务,以此类推。
下面是 React Fiber 的主要原理和流程:
-
构建 Fiber 树:
React 在渲染过程中构建一棵 Fiber 树,它与组件树一一对应。每个 Fiber 节点包含了组件实例、组件的状态、要渲染的元素、子节点等信息。 -
协调阶段:
在协调阶段,React 遍历 Fiber 树,根据组件的更新优先级和调度算法,决定哪些 Fiber 节点需要进行更新,哪些可以跳过。这个过程是可中断的。 -
构建副作用链表:
在协调阶段完成后,React 根据更新的结果构建一个副作用链表。副作用是对 DOM 的变更操作,如插入、更新或删除元素。副作用链表记录了所有需要在实际 DOM 更新阶段执行的操作。 -
提交阶段:
在提交阶段,React 会遍历副作用链表,根据副作用的类型和位置,执行实际的 DOM 更新操作。这个过程是同步的,不能中断。 -
渲染结果:
在完成提交阶段后,React 会将更新后的结果渲染到屏幕上,并触发相应的生命周期方法和钩子函数。
React Fiber 的引入使得 React 应用的更新过程变得更加灵活和高效,能够更好地适应不同的设备和交互场景。同时,它也为 React 引入了更多的优化策略和扩展能力,如异步渲染、错误边界、懒加载等功能。
如何构建副作用链表
下面是构建副作用链表的主要过程:
初始化副作用链表:
在协调阶段结束后,React Fiber 会初始化一个空的副作用链表,用于记录更新过程中的副作用操作。遍历 Fiber 树:
React Fiber 遍历 Fiber 树的过程中,对于每个需要更新的 Fiber 节点,会进行以下操作:
检查更新类型: React Fiber 根据节点的更新类型(如插入、更新或删除)来确定是否有副作用产生。根据更新类型的不同,会进行相应的副作用记录。
记录副作用: 如果节点有副作用产生,React Fiber 会将相关的操作记录到副作用链表中。这些操作可能包括对 DOM 的插入、更新或删除等。
遍历子节点: React Fiber 会继续遍历当前节点的子节点,重复上述步骤,直到遍历完整个 Fiber 树。
形成链表结构: 在遍历过程中,每个具有副作用的操作都会被记录到副作用链表中。这些操作会按照执行顺序依次连接形成一个链表结构。
返回副作用链表: 当遍历完成后,React Fiber 将最终形成的副作用链表返回,以便在提交阶段中执行实际的 DOM 更新操作。
通过构建副作用链表,React Fiber可以将更新操作的执行顺序记录下来,而不需要立即执行这些操作。这样做的好处是可以对副作用进行批量处理,优化性能,并且在提交阶段时可以根据需要进行优化,如合并多个操作、减少DOM 访问次数等。这种机制帮助提高了 React 应用的渲染性能和用户体验。
参考:React技术揭秘
相关文章:

React理念——Fiber架构的主要原理
React理念——Fiber架构的主要原理 React 理念CPU 的瓶颈IO 的瓶颈 Fiber的产生及原理如何构建副作用链表 React 理念 从官网看到React的理念: React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方式。它在 Facebook 和 Instagram 上表现优秀。 可见&a…...

[蓝桥杯练习题]确定字符串是否包含唯一字符/确定字符串是否是另一个的排列
确定字符串是否包含唯一字符 #include<bits/stdc.h> using namespace std; int main(){ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);map<char,int>m;string s;cin>>s;for(int i0;i<s.size();i){if(isalpha(s[i]))s[i]tolower(s[i]);if(…...

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:UIExtensionComponent (系统接口))
UIExtensionComponent用于支持在本页面内嵌入其他应用提供的UI。展示的内容在另外一个进程中运行,本应用并不参与其中的布局和渲染。 通常用于有进程隔离诉求的模块化开发场景。 说明: 该组件从API Version 10开始支持。后续版本如有新增内容࿰…...

Jenkins: 配合docker来部署项目
jenkins docker 部署 1 )测试将jenkins构建后的项目部署到docker的nginx镜像中 nginx 镜像内的默认目录在 /usr/share/nginx/html将待部署项目存放在 /usr/share/nginx/html 项目名称目录在Mac环境下的 jenkins系统 中,工程项目默认的路径在 ~/.jenkin…...

Leetcode 22. 括号生成
心路历程: 一开始看到左右括号,第一想到了栈。后来发现题目要求遍历所有的可能组合,第一想法是暴力for循环,但是不知道用几个for循环,所以想到递归和回溯。 虽然叫‘括号组合’,但是实际上这是一个满足规则…...

ChatGPT编程—实现小工具软件(批量替换文本、批量处理图像文件)
ChatGPT编程—实现小工具软件(批量替换文本、批量处理图像文件) 今天借助[小蜜蜂AI][https://zglg.work]网站的ChatGPT编程实现一个功能:批量处理文件及其内容,例如批量替换文本、批量处理图像文件等。 环境:Pycharm 2021 系统:…...

更安全的C gets()和str* 以及fgets和strcspn的用法
#include <stdio.h>int main() {char *str;gets(str);puts(str);return(0); }可以说全是错误 首先char *str没有指向一个分配好的地址,就直接读入,危险 ps: 怎么理解char *str "Hello World" 是将一个存储在一个只读的数据段中字符串常…...

专升本 C语言笔记-07 逗号运算符
1.逗号表达式的用法 就是用逗号隔开的多个表达式。逗号表达式,从左向右依次执行。 2.逗号表达式的特性 2.1.当没有括号时,第一个表达式为整个表达式的值。 代码 int x 3,y 5,a 0; a x,y; printf("a %d",a); 说明:因为逗号优先级最低,会…...

k8s之图形界面DashBoard【九】
文章目录 9. DashBoard9.1 部署Dashboard9.2 使用DashBoard 镇场 9. DashBoard 之前在kubernetes中完成的所有操作都是通过命令行工具kubectl完成的。其实,为了提供更丰富的用户体验,kubernetes还开发了一个基于web的用户界面(Dashboard&…...

基于Java+Springmvc+vue+element实现高校心理健康系统详细设计和实现
基于JavaSpringmvcvueelement实现高校心理健康系统详细设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐…...

python --阿里云(智能媒体管理/视频点播)
智能媒体服务获取token # alibabacloud_imm202009304.1.0 class Sample(object):智能媒体服务def __init__(self):self.access_key 111self.key_secret 222def weboffice_permission(self):return imm_20200930_models.WebofficePermission(renameFalse,readonlyTrue,histor…...

湖南麒麟SSH服务漏洞
针对湖南麒麟操作系统进行漏洞检测时,会报SSH漏洞风险提醒,具体如下: 针对这些漏洞,可以关闭SSH服务(前提是应用已经部署完毕不再需要通过SSH远程访问传输文件的情况下,此时可以通过VNC远程登录方法&#x…...

升级ChatGPT4.0失败的解决方案
ChatGPT 4.0科普 ChatGPT 4.0是一款具有多项出众功能的新一代AI语言模型。以下是关于ChatGPT 4.0的一些关键特点和科普内容: 多模态:ChatGPT 4.0具备处理不同类型输入和输出的能力。这意味着它不仅可以接收文字信息,还能处理图片、视频等多媒…...

常用图像滤波器,图像增强
滤波器 滤波器在图像处理中有各种各样的应用,它们可以用于去除噪声、平滑图像、增强图像特征等。以下是一些常见的滤波器及其主要应用: 均值滤波器(Mean Filter): 用于去除高斯噪声或均匀噪声。 平滑图像࿰…...

【PyTorch】成功解决ModuleNotFoundError: No module named ‘torch’
【PyTorch】成功解决ModuleNotFoundError: No module named ‘torch’ 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希…...

CommandInvokationFailure: Failed to update Android SDK package list. 报错的解决方法
将Unity升级到2021.3.36f1, 再次打开项目,结果出现“CommandInvokationFailure: Failed to update Android SDK package list. ”这样的警告,查看SDK版本最高只有到30,这应该就是Unity自动升级SDK的时候出现了错误,导致…...

9.用FFmpeg测试H.264文件的解码时间
1. Essence of Method 要测试对H.264文件的解码时间,可以使用FFmpeg进行操作。FFmpeg是一个开源的多媒体处理工具,可以用来处理视频和音频文件,包括解码H.264文件。以下是使用FFmpeg的命令行来测试解码时间的方法: ffmpeg -i in…...

重建3D结构方式 | 显式重建与隐式重建(Implicit Reconstruction)
在3D感知领域,包括3D目标检测在内,显式重建和隐式重建是两种不同的方法来表示和处理三维数据。它们各自有优势和局限,适用于不同的场景和需求。 显式重建(Explicit Reconstruction) 显式重建是指直接构建场景或物体的三…...

模型的参数量、计算量、延时等的关系
模型的参数量、计算量、延时等的关系 基本概念相互关系代码计算 基本概念 1.参数量:Params 2.计算量:FLOPs,Floating Point Operations,浮点运算次数,用来衡量模型计算复杂度。 3.延时:Latency 4.内存访问…...

Java映射(含源码)
在Java中,“映射”(Map)是一个存储键值对的数据结构,允许你通过键(Key)快速访问值(Value)。映射中的每个键都是唯一的,这意味着每个键都对应一个特定的值。Java提供了几种…...

JMeter 面试题及答案整理,最新面试题
JMeter中如何进行性能测试的规划和设计? 进行JMeter性能测试的规划和设计主要遵循以下几个步骤: 1、确定测试目标: 明确性能测试的目的和目标,比如确定要测试的系统性能指标(如响应时间、吞吐量、并发用户数等&#…...

lua脚本的基础内容
官方地址:http://luajit.org/ 官方wiki地址:http://wiki.luajit.org/Home 推荐书籍: OpenResty 最佳实践:https://moonbingbing.gitbooks.io/openresty-best-practices/content/ lua基础文档:https://www.runoob.com/l…...

MySQL语法分类 DDL(1)
DDL(1)(操作数据库、表) 数据库操作(CRUD) C(Create):创建 //指定字符集创建 create database db_1 character set utf8;//避免重复创建数据库报错可以用一下命令 create database if not exists db_1 character set utf8;R(Retrieve):查询 //查询所…...

苹果Find My App用处多多,产品认准伦茨科技ST17H6x芯片
苹果发布AirTag发布以来,大家都更加注重物品的防丢,苹果的 Find My 就可以查找 iPhone、Mac、AirPods、Apple Watch,如今的Find My已经不单单可以查找苹果的设备,随着第三方设备的加入,将丰富Find My Network的版图。产…...

Lua中文语言编程源码-第三节,更改lualib.h Lua标准库, 使Lua支持中文关键词(与所有的基础库相关)
源码已经更新在CSDN的码库里: git clone https://gitcode.com/funsion/CLua.git 在src文件夹下的lualib.h,是Lua的标准库模块。 Lua标准库一共有有个10个库,base, 基本用不着改,所以没加中文名称。 函数声明宏名英文库名中文库…...

Vue | 使用 ECharts 绘制折线图
目录 一、安装和引入 ECharts 二、使用 ECharts 2.1 新增 div 盒子 2.2 编写画图函数 2.3 完整代码结构 三、各种小问题 3.1 函数调用问题 3.2 数据格式问题 3.3 坐标轴标签问题 3.4 间隔显示标签 参考博客:Vue —— ECharts实现折线图 本文是在上…...

NVENC 视频编码器 API 编程指南 ( 中文转译 )
基于 NVIDIA Kepler™ 和更高版本 GPU 架构的 NVIDIA GPU 包含基于硬件的 H.264/HEVC/AV1 视频编码器(以下简称 NVENC)。NVENC 硬件采用 YUV/RGB 作为输入,并生成符合H.264/HEVC/AV1 标准的视频比特流。可以使用 NVIDIA 视频编解码器 SDK 中提…...

媒体发稿:澳门媒体发稿7个流程
推广平台澳门是一个重要的度假旅游娱乐终点,都是媒体领域热议的话题。对于澳门的媒体发稿营销推广要求,大家提供了一个简单易用的套餐系统软件,帮助大家在澳门媒体上发表推广文章。下面我们就根据7个阶段,详解构建这一套餐推广平台…...

Spring Web MVC入门(2)
学习Spring MVC Postman介绍 在软件工程中, 我们需要具有前后端分离的思想, 以降低耦合性. 但是在测试后端代码时,我们还得写前端代码测试,这是个令人头疼的问题. 那么我们如何测试自己的后端程序呢, 这就用到了一个工具: Postman. 界面介绍: 传参的介绍 1.普通传参, 也就…...

tomcat 实现会话绑定
Tomcat 后端服务器实现 Session ID会话保持 基础架构: 7-6 代理服务器nginx配置 7-3 tomcat 服务器 7-5 同理 测试: 此时刷新,会话ID一直在变,这样不好 如何解决呢? 不好的是确定ip之后,会一直在一台机上…...