React原理之Fiber双缓冲
前置文章:
- React原理之 React 整体架构解读
- React原理之整体渲染流程
- React原理之Fiber详解
-----读懂这一篇需要对 React 整体架构和渲染流程有大致的概念 😊-----
在前面的文章中,简单介绍了 Fiber 架构,也了解了 Fiber 节点的概念。
Fiber 节点是 Fiber 架构的核心概念之一,它是一种虚拟 DOM 的实现方式。
Fiber 本质上是一个对象, 使用了链表结构。
双重缓冲是一种渲染优化技术,其使用两个 Fiber 树来管理渲染,即当前树 current tree和工作树 work-in-progress tree。当前树代表屏幕上当前显示的内容,而工作树用于准备下一次的渲染更新,用以实现平滑的更新。
本篇将详细介绍 Fiber 架构的工作原理,即如何使用“双缓存”来完成 Fiber 树的构建与替换。
对于 fiber,我们已经有一些了解了。那么 fiber 节点构成的 fiber 树和页面上的 DOM 树有什么关系呢?我们经常看到的 fiber 双缓冲是什么?
双缓冲的概念
双缓冲(Double Buffering)是一种在计算机图形学和用户界面设计中常用的技术,简单来说,就是通过将绘制和显示过程分离,改善图像渲染的流畅性和视觉效果。
如上图,普通的绘图方式就像是直接在电脑屏幕上画图,用户可以看到绘图的每一个步骤,这样不太优雅。
双缓冲就类似于首先在内存上创建一个“虚拟屏幕”,所有的图形绘制工作都在虚拟屏幕上完成。这个虚拟屏幕就像是一个幕后的画布,绘图或称首先在这个虚拟屏幕上进行,用户看不到绘图的过程。
当虚拟屏幕上的图形绘制完成时,绘图程序会迅速将整个画面一次性拷贝到电脑屏幕上,替换掉之前的画面,这个拷贝过程是瞬间完成的。
这样,用户在屏幕上看到的图像始终都是完整的。
React 中的双缓冲 fiber 树
在 React 源码中,很多方法都需要接收两颗 FiberTree:
function cloneChildFibers(current, workInProgress) {// ...
}
current
是当前屏幕上显示内容对应的 FiberNode,workInProgress
指的是正在内存中构建的 FiberNode。
两个 FiberNode 会通过 alternate
属性相互指向:
current.alternate = workInProgress;
workInProgress.alternate = current;
每次状态更新都会产生新的workInProgress Fiber Tree
,通过current
与workInProgress
的替换,完成DOM
更新。
可以从首次渲染(mount)
和更新(update)
这两个阶段来看一下 FiberTree 的构建/替换流程。
首次渲染(mount)
首先我们先了解一下几个概念:
-
fiberRootNode:整个应用的根节点,
fiberRootNode
的current
会指向当前页面上已渲染内容对应Fiber树
,即current Fiber Tree
。 -
hostRootFiber: 它是一个具体的 Fiber 节点实例,具有 Fiber 节点的所有属性和方法。通常包含指向宿主环境(如 DOM)的引用,并且负责协调 React 组件与宿主环境之间的交互。
-
rootFiber:一个通用术语,用来指代 Fiber 树的根节点,包括
HostRootFiber
,其他类型的根 Fiber 等。 -
workInProgress Fiber Tree: 内存中构建的树,简写 WIP FiberTree。
-
current Fiber Tree: 页面显示的树。
// 示例
function App() {const [num, setNum] = useState(0);return <p onClick={() => setNum((prevNum) => prevNum + 1)}>{num}</p>;
}const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
流程一:
当执行 ReactDOM.createRoot 时:
// ReactFiberRoot.js 伪代码
function createFiberRoot() {//...// 创建 FiberRootNode 实例const root = new FiberRootNode(/* 参数 */);// 创建 HostRootFiber 实例const uninitializedFiber = createHostRootFiber(/* 参数 */);// 将 HostRootFiber 设置为 FiberRoot 的 current 属性root.current = uninitializedFiber;// ...return root;
}
此时会创建 fiberRootNode 和 hostRootFiber,fiberRootNode 通过 current
来指向 hostRootFiber。
即创建如下的结构:
由于是首屏渲染,页面中还没有挂载任何DOM
,所以fiberRootNode.current
指向的rootFiber
没有任何子Fiber节点
(即 current Fiber Tree 为空)。
流程二 (render)
接下来进入render阶段
,根据组件返回的 JSX 在内存中以深度优先原则依次创建wip FiberNode
并连接在一起构建 Fiber 树,即workInProgress Fiber Tree
。
生成的 wip FiberTree 里面的每一个 FiberNode 会和 current FiberTree 里面的 FiberNode 通过alternate
进行关联。但是目前 currentFiberTree 里面只有一个 HostRootFiber,因此就只有这个 HostRootFiber 进行了 alternate 的关联。
流程三 (commit)
当 wip FiberTree 生成完毕后,进入 commit 阶段,此时 FiberRootNode 就会被传递给 Renderer(渲染器),接下来就是进行渲染工作。已构建完的workInProgress Fiber Tree
在此阶段渲染到页面。
渲染工作完毕后,浏览器中就显示了对应的 UI,此时 FiberRootNode.current 就会指向这颗 wip Fiber Tree,曾经的 wip Fiber Tree 它就会变成 current FiberTree,完成了双缓存的工作:
更新(update)
点击p节点
触发状态改变而更新,这样就进入了 update。
流程四 (render)
update 会开启一次新的render阶段
并构建一棵新的workInProgress Fiber Tree
,流程和前面一样。
新的 wip Fiber Tree 里面的每一个 FiberNode 和 current Fiber Tree 的每一个 FiberNode 通过 alternate
属性进行关联。
流程五 (commit)
当 wip Fiber Tree 生成完毕后, workInProgress Fiber Tree
就完成了render阶段
的构建,进入commit阶段
渲染到页面上。
FiberRootNode 会被传递给 Renderer 进行渲染,此时宿主环境所渲染出来的真实 UI 对应的就是左边 Fiber Tree (此时还是 wip Fiber Tree) 对应的 DOM 结构,FiberRootNode.current 就会指向左边这棵树,右边的树就再次成为了新的 wip Fiber Tree。
以上两棵 fiber 树交替并更新 DOM 的过程这就是 fiber 双缓冲的原理。
扩展
在构建 workInProgress Fiber Tree 时会尝试复用 current Fiber Tree 中对应的 FiberNode 的数据,这个决定是否复用的过程就是 Diff 算法。留个位置放以后讲 Diff 算法的 🔗~
相关文章:

React原理之Fiber双缓冲
前置文章: React原理之 React 整体架构解读React原理之整体渲染流程React原理之Fiber详解 -----读懂这一篇需要对 React 整体架构和渲染流程有大致的概念 😊----- 在前面的文章中,简单介绍了 Fiber 架构,也了解了 Fiber 节点的…...
机器学习笔记三-检测异常值
检测异常值是数据预处理中非常重要的一步,因为异常值可能会影响模型的训练效果,甚至导致错误的结论。以下是几种常见的检测异常值的方法: 1. 箱线图(Box Plot): 箱线图是一种简单的统计图形,可…...
如何评估Redis的性能
导语 Redis是一款高性能的内存数据库,被广泛用于缓存、持久化、消息队列等各种场景。为了确保Redis的高性能运行,评估Redis的性能是非常重要的。本文将介绍如何评估Redis的性能,并从问题解决的角度探讨如何优化Redis的性能。 1. 性能评估指…...

RabbitMQ发布订阅模式Publish/Subscribe详解
订阅模式Publish/Subscribe 基于API的方式1.使用AmqpAdmin定制消息发送组件2.消息发送者发送消息3.消息消费者接收消息 基于配置类的方式基于注解的方式总结 SpringBoot整合RabbitMQ中间件实现消息服务,主要围绕3个部分的工作进行展开:定制中间件、消息发…...
Android8.1源码下对APK进行系统签名
在Android8.1上面对APK进行Android系统源码环境下的签名,发现签名时出现如下错误: Exception in thread "main" java.lang.ExceptionInInitializerError at org.conscrypt.OpenSSLBIOInputStream.(OpenSSLBIOInputStream. at org.conscrypt.OpenSSLX509Certificat…...
2024年城市客运安全员考试题库及答案
一、单选题 376.根据《机动车运行安全技术条件》(GB7258---2017),每个应急出口应在其附近设有"应急出口"字样,字体高度应大于或等于()mm。 A.20 B.30 C.40 D.50 答案:C 377.根…...

全网最全面的Nginx内容(理论与实践相结合)
一、Web服务 1.1 web服务访问流程 1.2 Web服务 1.2.1 Web服务器分类 Web服务分为Apache和Nginx 1.2.2 Apache经典的Web服务器 1.2.2.1 Apache介绍 Apache HTTP Server(简称Apache)是Apache软件基金会的一个开放源码的网页服务器,可以…...
(七)Flink Watermark
Flink 的 Watermark 是用来标识数据流中的一个时间点。Watermark 的设计是为了解决乱序数据处理的问题,尤其是涉及到多个分区的 Kafka 消费者时。在 Watermark 的作用下,即使某些数据出现了延迟到达的情况,也不会导致整个处理流程的中断。此外,Watermark 还能防止过期的数据…...
springboot 上传文件失败:The temporary upload location
Caused by: java.io.IOException: The temporary upload location [/tmp/tomcat.379776875189163783.8081/work/Tomcat/localhost/jcys-core] is not valid 原因: Linux下会自动清除tmp目录下10天没有使用过的文件,SpringBoot启动的时候会在/tmp目录下生…...

UNiapp之微信小程序导出Excel
效果如下 参考小程序:日常记一记 ---账单页面 主要功能是根据筛选条件导出账单明细列表,实现该功能主要借助一个工具(excel.js),可在文章顶部下载或者一下网盘下载 https://pan.baidu.com/s/1RLisuG4_7FGD0Cnwewyabg?pwdpd2a 提取码: pd2a…...
fsadsadsad
adsadsafsada...

高效录制新选择:2024年Windows录屏软件
录屏能帮助我们捕捉屏幕上的精彩瞬间,作为老师可以用来录制课程,作为会议记录员可以用来录制远程会议。那么有什么软件是适合windows录屏的呢?这次我们一起来探讨一下吧。 1.福昕录屏大师 链接:www.foxitsoftware.cn/REC/ 这款软…...
Java技术面试(一面)
1、相面对象 1、面相对象语言/Java三大特性是什么? 引出 封装、继承和多态。 2、多态有哪些形式?多态使用过吗? 重载、重写,接口和抽象类的多个实现。考察工作经验、代码重构经验、习惯。 3、Java接口和抽象类有什么区别?你是如何选择使用的? 考察OOP的理解和工作…...
docker修改数据目录
新建docker数据目录 mkdir /data/docker-data停止docker服务 systemctl stop docker把docker数据迁移到新目录 cp -r /var/lib/docker/* /data/docker-data/修改docker配置 vi /etc/docker/daemon.json #添加data-root参数 {"data-root":"/data/docker-dat...
Appium学习
一、基础配置 import unittest from appium import webdriver from appium.options.android import UiAutomator2Options from appium.webdriver.common.appiumby import AppiumBy from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support …...

回顾 | 瑞云科技亮相ICIC2024,虚拟仿真实训云平台引关注
2024年8月7日,天津市虚拟仿真学会主办的第二十届智能计算国际会议(ICIC2024)——虚拟仿真技术交流平行会议暨天津市虚拟仿真学会2024年暑期技术交流会在天津盛大召开。本次大会汇聚来自全国的顶尖专家、学者和行业领袖,共同探讨虚…...

libLZMA库iOS18平台编译
1.下载xz源码: 使用autogen.sh生成configure文件 2.生成makefile rm -rf ./build/iOS && mkdir -p ./build/iOS && cd ./build/iOS && ../../configure --host=arm-apple-darwin64 --prefix=`pwd`/Frameworks/lzma CC="xcrun -sdk iphoneos cl…...
《AI办公类工具PPT系列之二——iSlide AI》
一.简介 官网:iSlide- 让PPT设计简单起来 | PPT模板下载平台 iSlide AI是一款基于人工智能技术的PPT制作工具,它可以帮助用户快速高效地创建演示文稿 二.功能介绍 1. AI一键生成PPT 文档导入与解析:用户可以直接上传本地文档(如Word、Markdown、思维导图等),iSlide A…...

C语言基础(六)
一维数组: C语言中的数组是一种基本的数据结构,用于在计算机内存中连续存储相同类型的数据。 数组中的每个元素可以通过索引(或下标)来访问,索引通常是从0开始的。 数组的大小在声明时确定,并且之后不能改…...

什么是词向量?如何得到词向量?Embedding 快速解读
我第一次接触 Embedding 是在 Word2Vec 时期,那时候还没有 Transformer 和 BERT 。Embedding 给我的印象是,可以将词映射成一个数值向量,而且语义相近的词,在向量空间上具有相似的位置。 有了 Embedding ,就可以对词进…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...