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提供了几种…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...