1. React Fiber 的核心目标‌

  • 增量渲染‌:将大型更新拆解为可中断的小任务(时间切片),避免阻塞

  • 主线程‌优先级调度‌:动态管理任务执行顺序(如用户交互 > 动画 > 数据加载)。

  • 与浏览器协作‌:利用浏览器渲染周期(rAF)和空闲时间(rIC理念)优化性能。

一句话定义:

React Fiber是React 16+的核心重写算法,通过增量渲染和任务分片实现高性能异步更新。旨在解决传统同步渲染阻塞主线程导致的卡顿问题。

2. React Fiber 的核心原理

之前的版本中,React使用递归的方式处理组件树的更新,这个过程是同步的,一旦开始就不能中断,可能导致长时间占用主线程,造成界面卡顿,尤其是在处理复杂组件时。

Fiber是将组件树拆解为‌链表结构‌Fiber 节点(每个节点对应一个可中断/恢复的“工作单元”),通过‌优先级调度‌(如用户交互任务优先)和‌时间切片‌(利用浏览器空闲时间分批次处理任务),实现异步可中断的渲染流程。

Fiber 在协调阶段(Render Phase)增量构建虚拟树并标记副作用(如 DOM 更新),在提交阶段(Commit Phase)同步执行所有变更,同时通过‌双缓冲机制‌(交替使用 current 和 workInProgress 树)和‌副作用链表‌优化性能,从而支持并发模式(Concurrent Mode),显著提升复杂应用的响应速度与流畅度。

在 React 的 Fiber 架构中,requestAnimationFrame、‌链表‌ 和 ‌调度器‌三者紧密结合,主要体现在 ‌任务调度策略‌ 和 ‌执行效率优化‌

2.1. Filber中的链表(任务存储与遍历‌)

Fiber 树本身的链表结构‌和‌副作用链表(effect list)‌是‌两个不同的链表

2.1.1. Fiber 树链表(主链表)‌

作用‌:

表示组件树完整结构,用于协调阶段(reconciliation)遍历任务分片

数据结构‌:

每个 Fiber 节点通过 child、sibling、return 三个指针构成‌树形链表‌(深度优先遍历的线性化结构)。

class FiberNode {child: Fiber | null;    // 第一个子节点sibling: Fiber | null;  // 下一个兄弟节点return: Fiber | null;   // 父节点// ... 其他属性(type, stateNode 等)
}

特点‌:

用于递归的‌可中断恢复‌(通过保存当前处理的 Fiber 节点指针)。
是 React 处理组件更新的‌核心数据结构‌。

‌与调度器的关系‌
每个链表节点(FiberNode)包含任务信息优先级标记指针(child/sibling/return)
调度器通过链表实现‌可中断恢复‌:保存当前节点指针,下次从中断处继续

2.1.2. 副作用链表(effect list)‌

作用‌:

收集所有需要执行副作用的 Fiber 节点(如 DOM 操作、生命周期调用),在提交阶段(commit phase)批量处理。

‌数据结构‌:

通过 firstEffect、lastEffect、nextEffect 指针构成的‌单向链表‌。

class FiberNode {firstEffect: Fiber | null; // 链表头lastEffect: Fiber | null;  // 链表尾nextEffect: Fiber | null;  // 下一个副作用节点effectTag: Placement | Update | Deletion; // 副作用类型
}

‌特点‌:

Fiber 树的‌子集‌,仅包含需要处理的节点。
协调阶段动态构建,提交阶段直接遍历此链表执行 DOM 操作

副作用链表(effect list)的工作流程‌

每个Fiber节点在完成工作后,如果有副作用,会被添加到链表中。firstEffect和lastEffect用来指向链表的头和尾,nextEffect是每个节点的指针。在提交阶段,React遍历这个链表,依次处理每个副作用,如DOM更新生命周期方法的调用等。这种结构使得React能够高效地批量处理副作用,而不必在协调阶段频繁操作DOM,从而提高性能。

React Fiber 架构中任务调度与副作用处理的优先级机制:
于优先级,副作用链表可能并不直接管理优先级,而是由调度器决定哪些Fiber节点需要先处理。高优先级的更新会导致重新构建副作用链表,确保紧急的副作用先执行。例如,用户输入触发的更新可能打断正在进行的渲染,优先处理相关副作用,然后再处理低优先级的任务。

  • ‌中断与恢复‌:高优先级任务可中断当前协调过程,保留未完成的副作用链表,后续恢复时继续构建。
  • 多优先级链表‌:React 内部维护多个链表(如 pendingPassiveEffects),区分同步与异步(如 useEffect)副作用。
    •   ‌同步副作用‌:useLayoutEffect 在提交阶段同步执行。
      
    •   ‌异步副作用‌:useEffect 被推入异步队列,在浏览器空闲时处理。
      

在构建链表时,React可能采用深度优先的后序遍历方式确保子节点的副作用在父节点之前处理,这样在DOM操作时可以正确应用变更。例如,当子节点需要被删除时,先处理子节点的删除,再处理父节点的更新,避免父节点更新后子节点不存在导致的错误。

最后,需要理解副作用链表在React整个渲染流程中的位置。协调阶段(render phase)负责找出所有需要变更的节点构建副作用链表,提交阶段(commit phase)遍历链表执行变更。这种分离使得React可以异步处理渲染,提高响应能力。

2.1.3. 为什么分开设计?‌

1‌.关注点分离‌

Fiber 树负责‌任务调度和中断恢复‌(协调阶段)。
副作用链表负责‌高效执行 DOM 操作‌(提交阶段)。

‌2.性能优化‌:

提交阶段只需遍历少量副作用节点,避免全树遍历。
批量处理 DOM 更新,减少浏览器重排/重绘。

总结‌:
‌不是同一个链表‌,但副作用链表是 Fiber 树的衍生结构
Fiber 树是‌全局任务管理‌的骨架,副作用链表是‌局部优化‌的结果。
两者协作实现 React 的‌可中断渲染‌和‌高效更新‌

在这里插入图片描述

2.2‌. requestAnimationFrame(rAF)‌:调度时机控制‌

‌requestAnimationFrame(rAF)‌ 是浏览器提供的原生 API,用于在下一次屏幕刷新(通常是每秒 60 次,即 16.6ms/帧)前执行回调函数。

‌作用‌

在每一帧渲染前执行高优先级任务(如动画、UI 更新)

‌与调度器的关系‌:

React 调度器用 rAF 作为‌高优先级任务触发时机‌,确保视觉更新及时
避免 setTimeout 因时间不精确导致的丢帧问题

核心目标:

  • 动画与视觉更新‌:

rAF 确保回调函数在浏览器‌下一帧渲染前执行‌,与屏幕刷新率(60Hz)同步,避免丢帧。

  • React 中的应用‌:

高优先级任务对齐‌:React 将动画、布局更新等高优先级任务标记为与 rAF 同步执行。

‌避免布局抖动‌:在 rAF 回调中批量处理 DOM 读写,减少强制布局计算(如 offsetWidth)。

特性requestAnimationFramerequestIdleCallback
触发时机每帧开始前(16.7ms/60FPS)浏览器空闲时(无高优先级任务)
用途动画、视觉更新后台任务(日志、预加载)
优先级高(与渲染强相关)低(可被高优先级任务打断)
React调度参考影响高优先级任务分片启发低优先级任务分片(如并发渲染)
执行耗时限制需控制在3-4ms以内默认50ms(通过timeout参数可调)
兼容性IE10+需polyfill(如React的scheduler

2.3. React 自研调度器(Scheduler)

是其并发模式(Concurrent Mode)的核心底层机制,相比传统更新调度方式具有以下显著优势:

2.3.1.优先级调度‌

‌ 更精细的任务优先级控制‌

  • 5级优先级划分‌:
    Immediate(同步) > UserBlocking(用户交互) > Normal(默认) > Low(数据加载) > Idle(空闲任务)

协作流程示例‌

  • ‌用户点击按钮‌(Immediate 优先级):
    同步执行回调,更新状态,标记相关 Fiber 节点。
  • ‌触发动画‌or搜索建议(UserBlocking 优先级):
    将更新任务放入 rAF 队列,确保下一帧渲染前完成。
  • ‌数据加载‌(Low 优先级):
    拆分任务为 5ms 的块,在调度器检测到空闲时逐步执行。
  • 动态调整‌:高优先级任务可中断低优先级任务(如渲染中途响应用户点击)。
2.3.2.避免浏览器主线程阻塞
1.时间切片(Time Slicing)的概念

时间切片逻辑‌:将任务拆分5ms 的块,动态检查剩余时间,通过shouldYield()判断是否让出主线程,保证UI响应。优先处理用户输入高优先级事件。

用于将渲染任务分解成更小的单元,这样可以在浏览器的空闲时段执行这些任务,避免阻塞用户交互。这听起来类似于浏览器的requestIdleCallback API,允许在空闲时间执行任务,但React可能自己实现了更精细的控制。

requestIdleCallback(rIC)的理念‌

空闲时段处理低优先级任务‌:rIC 在浏览器空闲时执行非紧急任务(如日志、预加载),避免干扰关键渲染和交互。

2.‌基于MessageChannel的调度‌:

React 自研调度器,通过 MessageChannelsetTimeout ‌模拟空闲检测‌
MessageChannel相比setTimeout,利用事件循环的宏任务机制更精准控制执行时机,避免任务堆积导致卡顿。

React Fiber 未直接使用 rIC‌:这是因为rIC的浏览器兼容性触发频率不够理想。React的调度器会将任务分成小的时间片,并在每个时间片结束时检查是否有更高优先级的任务需要处理,从而避免长时间阻塞主线程。

2.3.3. 更智能的后台任务处理‌

空闲期利用‌:
通过requestIdleCallback的polyfill(兼容方案),在浏览器空闲时执行低优先级任务(如日志上报、预渲染)。

‌任务饥饿保护‌:
防止低优先级任务因长期无法执行被“饿死”(超过超时时间会强制提升优先级)。

2.3.4. 与React深度集成‌

‌ 协调器(Reconciler)联动‌:

调度器知晓Fiber节点结构,可精准暂停/恢复渲染任务,实现可中断渲染。

‌并发特性基础‌:

支持startTransition、useDeferredValue等API的底层依赖。

对比传统调度方案‌

能力传统setState更新React调度器
任务中断✗ 不可中断✔ 高优任务可中断低优任务
浏览器阻塞可能阻塞主线程通过时间切片避免阻塞
优先级控制无差别处理5级动态优先级
后台任务利用依赖手动实现内置空闲期调度

2.4 双缓冲机制

2.4.1. 双缓冲的定义

Fiber 架构的核心机制‌,用于在 ‌协调阶段(Reconciliation)‌ 和 ‌提交阶段(Commit)‌ 之间高效管理组件状态更新,确保 React 的 ‌可中断渲染‌ 和 ‌一致性更新‌

双缓冲是计算机图形学中的经典技术,指 ‌同时维护两套数据结构‌:

  • 当前缓冲(Current)‌:正在渲染或已渲染的 UI 状态(对应屏幕上显示的内容)。
  • 工作缓冲(WorkInProgress,WIP)‌:正在计算的新状态(尚未提交到屏幕)。

React 借用这一概念,在 Fiber 架构中维护 ‌两棵 Fiber 树‌:

  • current 树‌:当前已渲染的 Fiber 树(对应真实 DOM)。
  • workInProgress 树‌:正在构建的新 Fiber 树(用于计算更新)。
2.4.2. 双缓冲的核心流程‌

‌(1) 协调阶段(Reconciliation)‌

  • React 从 current 树克隆出 workInProgress 树(通过 alternate 指针关联)。
  • workInProgress 树上进行 ‌Diff 计算‌标记需要更新的节点(effectTag)。
  • 如果任务被中断(如高优先级任务插入),可以丢弃 workInProgress 树并重新开始,而不会影响 current 树(已渲染的 UI)。

‌(2) 提交阶段(Commit)‌
当 workInProgress 树构建完成,React 执行 ‌原子性切换‌:

root.current = finishedWork; // 切换 current 和 workInProgress

此时:

  • 新的 workInProgress 树变为 current 树(对应最新 UI)。
  • 旧的 current 树变为新的 workInProgress 树(供下次更新使用)。

通过维护两棵 Fiber 树(currentworkInProgress),实现:

  • 计算与渲染分离。
  • 高优先级任务抢占。
  • 无闪烁的 UI 更新。

最终提升复杂应用的流畅度和响应速度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/93715.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93715.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/93715.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Shader开发(五)什么是渲染管线

在计算机图形学中,渲染管线(Rendering Pipeline) 是图形处理器(GPU)将3D网格数据转化为屏幕图像的核心流程。无论是炫酷的游戏画面还是逼真的动画场景,这一切都离不开渲染管线的默默工作。对于想要学习着色…

CentOS7 使用Docker安装MinIO完整教程

目录 1. MinIO简介 什么是MinIO? 为什么选择Docker安装? 2. 环境准备 检查Docker状态 检查防火墙设置 创建存储目录 3. 快速启动MinIO 基础启动命令 验证启动状态 4. 配置持久化存储 停止并删除临时容器 使用数据卷启动MinIO 验证数据持久化 5. 访问MinIO控制台…

【数据库】时序数据库选型指南:从大数据视角看IoTDB的核心优势

文章目录前言-官网链接一、时序数据管理的时代挑战二、时序数据库选型的六大核心维度1. 数据模型设计2. 写入与查询性能3. 存储效率4. 系统扩展性5. 生态兼容性6. 运维复杂度三、IoTDB的技术架构解析1. 存储引擎创新2. 计算引擎优势3. 分布式架构设计四、行业解决方案对比1. 能…

【25-cv-08364】Keith携Hello Angel版权图发案

Hello Angel版权图案件号:25-cv-08364起诉时间:2025/7/22原告:Angelea Clark Van Dam原告律所:Keith受理法院:伊利诺伊州北区地方法院原告介绍原告是是一位来自澳大利亚的艺术家,笔名为Hello Angel&#xf…

SkSurface---像素的容器:表面

如果说 SkCanvas 是画布,是所有绘图操作的提供者的话,那么 SkSurface 就是画布的容器,我们称之为表面,它负责管理画布对应的像素数据。这些像素数据可以是在内存中创建的,也可以是在 GPU 显存中创建的。创建一个空白表…

26.(vue3.x+vite)以pinia为中心的开发模板

效果截图 代码实现 HelloWorld.vue <template><div style="padding: 20px;">介绍:<br>1:使用class 来减少pinia(store)的代码量<br>

华为AI Agent智能园艺助手开发案例

一、引言与行业背景 在数字化与智能化日益渗透我们生活的今天&#xff0c;园艺这一传统而充满生机的领域&#xff0c;也迎来了智能化的革新。华为AI Agent智能园艺助手通过融合人工智能与园艺专业知识&#xff0c;为用户提供一站式、个性化的园艺养护解决方案&#xff0c;彻底改…

Linux Flathub软件管理方法 使用指南

Flathub 使用指南&#xff1a;软件安装、管理及常用软件推荐 一. 什么是 Flathub&#xff1f; Flathub 是 Flatpak 应用程序的主要分发中心&#xff0c;类似于 Linux 上的"应用商店"。它提供了一种跨发行版的软件打包和分发方式&#xff0c;让用户可以在任何 Linux 发…

GitLab 18.2 发布几十项与 DevSecOps 有关的功能,可升级体验【二】

沿袭我们的月度发布传统&#xff0c;极狐GitLab 发布了 18.2 版本&#xff0c;该版本带来了议题和任务的自定义工作流状态、新的合并请求主页、新的群组概览合规仪表盘、下载安全报告的 PDF 导出文件、中心化的安全策略管理&#xff08;Beta&#xff09;等几十个重点功能的改进…

​​免费语音转换服务(TTS)全面指南

​​​​1. TTS技术概述​​ TTS&#xff08;Text-to-Speech&#xff09;通过AI将文字转化为自然语音&#xff0c;核心技术包括​​深度神经网络&#xff08;DNN&#xff09;​​、​​语音韵律建模​​和​​声学合成​​。其核心优势在于&#xff1a; ​​多语言支持​​&a…

正则化都是放在模型的哪个位置呢?

✅ 什么是“正则化”&#xff1f;在神经网络中&#xff0c;正则化&#xff08;Regularization&#xff09; 抑制过拟合的技巧 目的是让模型在训练集和测试集上都表现得好&#xff08;泛化能力强&#xff09;。&#x1f9e0; 常见的正则化手段包括&#xff1a;方法类型通常放在哪…

Python毕业设计 | 基于协同过滤的智能商品推荐与数据大屏系统(Vue+Flask+Scikit-learn,附源码+文档)

个人介绍&#x1f3af; 毕业设计私人教练 专注计算机毕设辅导第 6 年&#xff0c;累计 1v1 带飞 800 同学顺利通关。从选题、开题、代码、论文到答辩&#xff0c;一条龙陪跑&#xff1b;擅长把导师的 “模糊要求” 变成能落地的技术方案。白天写方案&#xff0c;晚上改论文&…

基于千问2.5-VL-7B训练识别人的表情

一、安装LLaMA-Factory 我们使用LLaMA-Factory来进行微调&#xff0c;安装LLaMA-Factory来参考文章&#xff1a; 大模型微调工具LLaMA-Factory的安装流程-CSDN博客 二、下载千问2.5-VL-7B模型 我们使用千问2.5-VL-7B多模态模型来进行微调 通义千问2.5-VL-7B-Instruct 下载…

Android屏幕适配:从dp到px的转换与今日头条适配方案详解

前言 在Android开发中&#xff0c;屏幕适配一直是一个重要且复杂的话题。不同设备有着不同的屏幕尺寸、分辨率和像素密度&#xff0c;如何让应用在各种设备上都能良好显示&#xff0c;是每个开发者都需要面对的问题。本文将深入探讨Android系统中dp到px的转换原理&#xff0c;并…

nvim 缩进4空格

要把 Neovim 配置为缩进 4 空格&#xff0c;并适用于所有语言&#xff08;或某些语言如 C/C&#xff09;&#xff0c;你只需要设置这三个核心选项即可&#xff1a;✅ 通用方式&#xff1a;在 init.lua 或 options.lua 中添加 vim.opt.tabstop 4 -- 一个 <Tab> 等…

pdw估计edw怎么估计

问题一、pdw估计edw怎么估计PDW&#xff08;Pulse Descriptor Word&#xff09;数据是雷达接收到的每一个脉冲的瞬时特征数据&#xff0c;EDW&#xff08;Emitter Descriptor Word&#xff09;是对某一辐射源&#xff08;发射机&#xff09;整体特性的估计。PDW 是每一个脉冲的…

TS语法最佳实践

switch 的 case不能使用条件表达式JavaScript 允许在 switch 的 case 中使用条件表达式&#xff0c;但这种用法实际上是无效的&#xff0c;因为 case 的值会被隐式地转换为布尔值。TypeScript 明确禁止这种用法&#xff0c;以避免隐式类型转换导致的逻辑错误。建议使用 if-else…

行业热点丨仿真历史数据难以使用?如何利用几何深度学习破局,加速汽车工程创新

01、AI 驱动研发升级&#xff1a;几何深度学习创造行业新价值人工智能正加速推动各行业研发能力升级。麦肯锡最新报告显示&#xff0c;该技术在制药、化工和航空航天等领域的应用&#xff0c;有望为相关企业创造高达5600亿美元的经济价值。 AI 技术应用的先行者&#xff0c;全球…

JSBridge原理与实现全解析

JSBridge 是用于连接 JavaScript&#xff08;H5&#xff09; 和原生应用&#xff08;iOS/Android&#xff09;的桥梁&#xff0c;允许它们之间相互调用方法。 &#x1f309; 一、JSBridge 双向通信流程图 #mermaid-svg-AoDVdJL2VJBnTJ2Q {font-family:"trebuchet ms"…

Mockito:Java单元测试Mock框架

文章目录一、写在前面1、简介2、依赖二、使用1、基本使用2、注解&#xff08;1&#xff09;开启注解&#xff08;2&#xff09;Mock 注解&#xff08;3&#xff09;DoNotMock 注解&#xff08;4&#xff09;Spy 注解&#xff08;5&#xff09;Captor 注解&#xff08;6&#xf…