React Fiber 浅谈

React Fiber

背景

React 为了描述组件状态和Dom的关系,采用虚拟DOM来表示真实DOM。
每个组件在每次渲染时会创建一个新的Virtual DOM,React会把新的Virtual DOM树与现有的相比较,然后将一系列转变应用于真实DOM。

在 React 15 的版本中,虚拟 Dom 采用 Stack 架构实现,diff 更新的过程是 同步循环递归,这就导致只有所有的 组件 更新之后,才会让出主进程进行 Dom 渲染。

虚拟 Dom 树如果直接更新,当组件非常多时,给数据更新的 diff 带来了很大压力。如果 js占据主线程去做比较,渲染线程便无法做其他工作,用户的交互得不到响应,所以便出现了react fiber。

什么是 Fiber

按照名词解释,这是一种数据结构(也可叫执行单元),将虚拟 Dom Tree 转变为 可支持·断点遍历重启 的 链表(单链表树结构)。

按照动词解释,这是协程,React Fiber 把一次更新过程碎片化,细致控制虚拟 Dom 更新 和 渲染 Dom 展示这些操作的执行顺序。

基于碎片化更新的过程,每次执行完单个碎片更新,就会把主线程交给 React 其他模块,来处理其他紧急任务。如果没有紧急任务,那就继续更新。

工作原理

Fiber 节点保存了 Dom 节点,Fiber 树和 Dom 树互相呼应。

通过判断当前执行帧空闲空间,来选择执行对应优先级的执行任务,在当前帧结束前再次判断是否有剩余时间和任务来支持执行,没有则执行浏览器渲染任务,并循环这一过程来最大化提升渲染效率。

利用requestAnimationFrame来确保每一帧执行的任务。

利用requestIdleCallback 来指定执行哪些低优先级的任务。如果遇到超过正常帧的任务,执行完毕后就需要立即归还控制权,并使用 requestIdleCallback 来再次申请下一次更新的时间片。requestIdleCallback 会给 callback 传递IdleDeadline 来判断任务的操作状态。

  • timeRamining():用来判断用户代理预计还剩余多少闲置时间。
  • didTimeout:用来判断当前的回调函数是否因超时而被执行。

双缓存 Fiber 树

  1. 基于渲染内容的 CurrentFiber Tree
  2. 内存中实时构建的 WorkInProgress Fiber Tree(节点之间通过 altermnate 属性连接)

根节点通过指针 current 在不同的 FiberTree 和 RootFiber 之间切换,完成 current Fiber Tree 指向的切换。

更新内容在 WorkInProgress Fiber Tree 构建完成后,经由 Renderer 渲染到页面上后,根节点的 current 指向 WorkInProgress Fiber 树,基于互相呼应的原理,这棵 WorkInProgress Fiber Tree 此时变成了 CurrentTree。当下一次 State 更新时,构建新的 WorkInProgress Fiber Tree, 然后再次执行上述操作,便完成了 Tree 的 替换,也就是 Dom 的更新

Render 阶段

此处的 Render 并非指浏览器渲染页面,而是虚拟 Dom 和 真实 Dom 的 Diff 过程,并进行变化的内容标记收集。**Render 是一个可以被打断的过程。 ** 在该阶段构建一棵Fiber tree,产生和虚拟 Dom 一一对应的任务,并且产出最后的更新 List(Effect List)。

收集 Effect List

  1. 如果当前节点需要更新,则使用对应tag标记当前节点状态(props, state, context等);
  2. 为每个子节点创建fiber。
    1. 并为 需要更新的 Fiber 添加两个属性:
      • firstEffect:指向第一个有变更的子fiber。
      • lastEffect:指向最后一个有变更的子fiber。

而我们需要收集的就是中间nextEffect,最终形成一个单链表。

  1. 如果没有产生child fiber,则结束该节点,把effect list归并到return,把此节点的兄弟节点作为下一个遍历节点;否则把子节点作为下一个遍历节点;
  2. 如果有剩余时间,则开始下一个节点,否则等下一次主线程空闲再开始下一个节点;
  3. 如果没有下一个节点了,进入pendingCommit状态,此时effect list收集完毕,结束。

Commit 阶段

Commit 阶段会将根据 EffectList 将上述操作中标记需要变更的 Fiber 更新到 DOM 树上,此阶段为了确保 UI 更新的连续性,是不可中断的过程。

到这里,整个 Fiber 的 刷新和更新过程就完成了。

总结

Fiber 是基于碎片化任务和和交替变更浏览器控制权,来达到更好的更新效果。其通过双缓存机制,在其 Render 阶段比较 虚拟 Dom 树和 真实 Dom,并进行节点变更标记和收集变更依赖,在 Commit 阶段更新 被标记 Fiber 节点到真实 Dom 树完成整个更新和刷新流程。

相关推荐
镜宇秋霖丶7 小时前
2026.5.6@霖宇博客制作中遇见的问题
前端·javascript·vue.js
小李子呢02119 小时前
前端八股Vue---Vue-router路由管理器
前端·javascript·vue.js
洛_尘10 小时前
Python 5:使用库
java·前端·python
Bigger10 小时前
Bun 能上生产吗?我的实战结论
前端·node.js·bun
kyriewen12 小时前
你的前端滤镜慢得像PPT?用Rust+WebAssembly,一秒处理4K图
前端·rust·webassembly
kyriewen1112 小时前
你等的Babel编译,够喝三杯咖啡了——用Rust重写的SWC,只需眨个眼
开发语言·前端·javascript·后端·性能优化·rust·前端框架
IT_陈寒12 小时前
SpringBoot自动配置坑了我,原来要这样绕过去
前端·人工智能·后端
东方小月12 小时前
Claude Code 完整上手指南:MCP、Skills、第三方模型配置一次搞定
前端·人工智能·后端
XZ探长13 小时前
基于 Trae Solo 移动办公修复 Vue3 前端服务问题
前端
小程故事多_8013 小时前
[大模型面试系列] 深度解析ReAct框架,大模型Agent的“思考+行动”底层逻辑
人工智能·react.js·面试·职场和发展·智能体