react的fiber 用法

在 React 里,Fiber 是 React 16.x 及后续版本采用的协调算法,它把渲染工作分割成多个小任务,让 React 可以在渲染过程中暂停、恢复和复用任务,以此提升渲染性能与响应能力。在实际开发中,你无需直接操作 Fiber 节点,不过你可以借助 React 的 API 来利用 Fiber 的特性。下面从几个方面为你讲解 Fiber 的用法。

1. 异步渲染

Fiber 架构实现了异步渲染,这意味着 React 能在渲染期间暂停工作,处理高优先级的事件。你可以通过 React.lazySuspense 来实现代码分割和异步加载组件。

jsx 复制代码
import React, { lazy, Suspense } from 'react';

// 异步加载组件
const LazyComponent = lazy(() => import('./LazyComponent'));

function App() {
    return (
        <div>
            <Suspense fallback={<div>Loading...</div>}>
                <LazyComponent />
            </Suspense>
        </div>
    );
}

export default App;

2. 优先级调度

Fiber 架构支持任务优先级调度,借助 React.unstable_runWithPriority 函数,你能设置不同任务的优先级。

jsx 复制代码
import React, { unstable_runWithPriority as runWithPriority } from 'react';

function App() {
    const handleClick = () => {
        runWithPriority('userBlocking', () => {
            // 高优先级任务
            console.log('High priority task');
        });

        runWithPriority('normal', () => {
            // 普通优先级任务
            console.log('Normal priority task');
        });
    };

    return (
        <button onClick={handleClick}>
            Run tasks with different priorities
        </button>
    );
}

export default App;

3. 时间切片

Fiber 利用时间切片技术,把渲染工作拆分成多个小任务,避免长时间阻塞主线程。在 React 中,你可以使用 React.memo 来对组件进行记忆化,减少不必要的渲染。

jsx 复制代码
import React from 'react';

// 记忆化组件
const MemoizedComponent = React.memo(({ data }) => {
    return <div>{data}</div>;
});

function App() {
    const [count, setCount] = React.useState(0);

    return (
        <div>
            <button onClick={() => setCount(count + 1)}>
                Increment
            </button>
            <MemoizedComponent data={count} />
        </div>
    );
}

export default App;

总结

  • 异步渲染 :借助 React.lazySuspense 实现代码分割和异步加载组件。
  • 优先级调度 :使用 React.unstable_runWithPriority 函数设置任务优先级。
  • 时间切片 :通过 React.memo 记忆化组件,减少不必要的渲染。

Fiber 是 React 16.x 及以后版本所采用的协调算法,其核心目标在于提升 React 应用的渲染性能和响应能力。下面详细介绍 React Fiber 的核心技术点:

核心技术

1. 架构目标与动机

  • 渲染性能优化:传统的协调算法在处理大型组件树时,可能会出现长时间阻塞主线程的情况,导致页面卡顿。Fiber 通过将渲染任务拆分成多个小任务,允许在渲染过程中暂停、恢复和重新排序任务,避免长时间占用主线程,从而提升渲染性能。
  • 优先级调度:Fiber 架构支持任务优先级调度,能够根据任务的重要性和紧急程度对任务进行排序,优先处理高优先级的任务,如用户交互事件,提高应用的响应能力。

2. 核心概念

  • Fiber 节点:Fiber 节点是 Fiber 架构中的基本单元,每个 React 元素都对应一个 Fiber 节点。Fiber 节点包含了组件的状态、属性、副作用等信息,同时还维护了与其他 Fiber 节点的关系,如父节点、子节点和兄弟节点。
  • Fiber 树 :由多个 Fiber 节点组成的树形结构,代表了 React 应用的组件树。Fiber 树有两棵,分别是 current 树和 workInProgress 树。current 树表示当前屏幕上显示的内容,workInProgress 树是正在构建的新树,构建完成后会替换 current 树。
  • 任务调度:Fiber 架构将渲染任务拆分成多个小任务,每个任务对应一个 Fiber 节点的处理。调度器会根据任务的优先级和时间片来决定何时执行任务,确保高优先级任务能够及时处理。

3. 工作流程

  • 调度阶段(Scheduler) :当组件的状态或属性发生变化时,React 会创建一个新的 workInProgress 树,并将任务添加到调度器中。调度器会根据任务的优先级和时间片来决定何时执行任务。如果当前有高优先级的任务(如用户交互事件),调度器会暂停当前正在执行的任务,优先处理高优先级任务。
  • 协调阶段(Reconciler) :调度器选择一个任务后,会将其交给协调器处理。协调器会递归遍历 workInProgress 树,比较 current 树和 workInProgress 树的差异,标记出需要更新、插入或删除的节点。这个过程是可以暂停和恢复的,因为每个 Fiber 节点的处理都是一个独立的小任务。
  • 提交阶段(Renderer):当协调阶段完成后,所有的差异都已经标记好。提交阶段会将这些差异一次性应用到真实 DOM 上,更新页面显示。提交阶段是不可中断的,确保页面的一致性。

4. 优先级调度

  • 任务优先级 :Fiber 架构定义了多种任务优先级,如 ImmediatePriority(最高优先级,立即执行)、UserBlockingPriority(用户交互相关的高优先级任务)、NormalPriority(普通优先级任务)、LowPriority(低优先级任务)和 IdlePriority(空闲时执行的任务)。
  • 优先级调度算法:调度器会根据任务的优先级和时间片来决定任务的执行顺序。高优先级的任务会优先执行,并且可以中断低优先级的任务。当高优先级任务执行完成后,低优先级任务会继续执行。

5. 异步渲染

  • 时间切片:Fiber 利用时间切片技术,将渲染工作拆分成多个小任务,每个任务执行一段时间后暂停,将控制权交还给主线程,让主线程有机会处理其他事件,如用户交互、动画等。这样可以避免长时间阻塞主线程,提高应用的响应能力。
  • Suspense 和 Lazy 组件 :Fiber 架构支持异步加载组件,通过 React.lazySuspense 可以实现代码分割和异步渲染。当组件需要异步加载时,Suspense 组件可以显示一个加载提示,直到组件加载完成。

6. 副作用处理

  • 副作用(Effect) :在 React 中,副作用是指那些会影响外部环境的操作,如数据获取、订阅、DOM 操作等。Fiber 架构通过 useEffectuseLayoutEffect 等 Hooks 来处理副作用。
  • 副作用调度 :副作用的执行也遵循优先级调度原则。useEffect 会在提交阶段之后异步执行,不会阻塞页面渲染;useLayoutEffect 会在提交阶段同步执行,用于处理需要立即更新 DOM 的副作用。
相关推荐
Mapmost8 分钟前
你的3DGS数据为何难以用在项目里?Web端开发实战指南
前端
举个栗子dhy10 分钟前
第一章、React + TypeScript + Webpack项目构建
前端·javascript·react.js
大杯咖啡14 分钟前
localStorage与sessionStorage的区别
前端·javascript
RaidenLiu26 分钟前
告别陷阱:精通Flutter Signals的生命周期、高级API与调试之道
前端·flutter·前端框架
非凡ghost26 分钟前
HWiNFO(专业系统信息检测工具)
前端·javascript·后端
非凡ghost28 分钟前
FireAlpaca(免费数字绘图软件)
前端·javascript·后端
非凡ghost35 分钟前
Sucrose Wallpaper Engine(动态壁纸管理工具)
前端·javascript·后端
拉不动的猪36 分钟前
为什么不建议项目里用延时器作为规定时间内的业务操作
前端·javascript·vue.js
该用户已不存在43 分钟前
Gemini CLI 扩展,把Nano Banana 搬到终端
前端·后端·ai编程
地方地方1 小时前
前端踩坑记:解决图片与 Div 换行间隙的隐藏元凶
前端·javascript