React Fibber架构设计理解

React Fibber架构设计理解

前置知识

了解前端的人应该都听过:JavaScript 是单线程的,浏览器是多线程的

对于多线程浏览器来说,除了要处理JS的线程外,还需要处理包含事件系统、定时器/延时器、网络请求等各种任务线程。当然也包含了DOM的UI渲染。而JS又是可以操作DOM的

这就意味着JS线程和渲染是互斥的,这两个线程不能穿插执行,必须串行,当其中一个线程执行时,另一个线程只能挂起等待

具有相似特征的还有事件线程,浏览器Event-loop机制决定了事件任务是由一个异步队列来维持的,当事件被触发时,对应的任务不会立刻被执行,而是由事件线程把它添加到任务队列的末尾,等待JS的同步代码执行完毕后,在空闲时间里执行出队

这种机制下,JS线程长时间占用了主线程,在用户眼中就是所谓的“卡顿”,其实在渲染层面来说,就是在等待界面更新。试想一下,作为用户,当我们使用的页面卡顿之后,一般会做什么?于我而言,我会在页面反复点击。但当我点击触发的事件,事件线程其实也在等待JS,这就是为什么我们点击也无济于事。这其实也是Stack Rconciler(React 协调引擎)后期面临的困境。

为什么会出现这样的困局

出现这一困境的原因是:Stack Rconciler是一个同步递归的过程。这里简单说一下同步递归的原理:

当在调用setState时,React会立即比对虚拟DOM,这个过程是深度优先遍历,利用了JS原生的函数调用栈。它的工作方式:一旦开始,React就会递归处理每一个组件,知道整颗树对比完成;**不可中断性:JS是单线程的,所以一旦React开始递归后,页面就开始出现”卡顿“,尤其是组件树特别深的情况下,卡顿更明显。

什么是Fiber,它是如何解决问题的

Fiber解决的就是同步递归的问题,所以在React16版本后重写了底层框架,引入Fiber。Fiber将原本密不可分的同步递归工作拆分成了很多小的工作单元。从架构层面来看,Fiber是对React核心算法的重写,从编码角度来看,Fiber是Fiber树节点的单位,从工作流的角度来看,Fiber节点保存了组件需要更新的状态和副作用。
按照React官方的说法,Fiber架构应用的目的是实现“增量渲染”(将一个渲染任务分解为多个渲染任务,而后将其分散到多个帧里面),实现增量渲染的目的是为了实现任务可中断、可恢复,并给不同的任务赋予不同的优先级,最终达成更加顺滑的用户体验。

Fiber架构核心:可中断、可恢复、优先级

从图中我们可以看到为了实现可中断和优先级,两层架构变成了三层架构。在这套架构模式下,更新的工作流变成了这样:首先每个更新任务(假设为A)都会被赋予一个优先级。当更新任务抵达调度器时,高优先级的更新任务会更快的被调度到Reconciler层,此时若有新的更新任务(假设为B),抵达调度器,调度器会先检查它的优先级,如果此时B的优先级任务比A高,那么当前处于Reconciler层的A任务会中断,调度器会将任务B推入到Reconciler层,当B任务完成渲染后,新一轮调度开始,之前被中断的A任务会重新被推入Reconciler层,继续它的渲染之旅,这就是“可恢复”

image

为什么React19的Fiber更强大

在React19版本中,Filber实现了更智能的资源管理

  1. 自动批处理强化:利用Fiber任务调度的特性,更多的状态更新被合并,减少重复渲染。
  2. Server Components深度整合:Fiber能够处理流式渲染,让组件在服务端生成后,分批次注入到客户端的Fiber树中。
  3. Transition优化:在React19中 useTransition可以完美地非紧急更新标记为低优先级,确保搜索框永远是丝滑的。
posted @ 2026-03-06 21:07  前端加油站  阅读(2)  评论(0)    收藏  举报