Fiber是什么

在本质上,Fiber是一个JavaScript对象,代表React的一个工作单元,它包含了与组件相关的信息。

当React开始工作时,它会沿着Fiber树形结构进行,试图完成每个Fiber的工作(例如,比较新旧props,确定是否需要更新组件等)。如果主线程有更重要的工作(例如,响应用户输入),则React可以中断当前工作并返回执行主线程上的任务。

Fiber不仅仅是代表组件的一个内部对象,它还是React的调度和更新机制的核心组成部分。

为什么需要Fiber?React Fiber架构的改进

在React 16之前的版本中,是使用递归的方式处理组件树更新,称为堆栈调和(Stack Reconciliation),这种方法一旦开始就不能中断,直到整个组件树都被遍历完

Fiber可以理解为是React自定义的一个带有链接关系的DOM树,每个Fiber都代表了一个工作单元,React可以在处理任何Fiber之前判断是否有足够的时间完成该工作,并在必要时中断和恢复工作。

将渲染任务拆分为多个小任务(Fiber节点),利用浏览器的空闲时间分片执行。实现可中断的异步渲染,解决同步递归更新导致的卡顿问题。

好处

可以提升性能和响应性,将渲染任务拆分为多个小任务(Fiber节点),利用浏览器的空闲时间分片执行。

优先级调度,react引入了任务的优先级概念,react可以根据任务的重要性处理高优先级的任务,确保关键任务的及时执行

可中断渲染。fiber可以在执行过程中中断和恢复,react可以在处理复杂更新的时候暂停当前那个任务处理更紧急的任务,再继续之前的工作,提升流畅度

源码层面

1.fiber节点

每个组件对应一个fiber节点,包括组件的一些状态属性,可理解为更强大的虚拟dom 

简化版fiber对象belike

{
  type: 'h1',  // 组件类型
  key: null,   // React key
  props: { ... }, // 输入的props
  state: { ... }, // 组件的state (如果是class组件或带有state的function组件)
  child: Fiber | null,  // 第一个子元素的Fiber
  sibling: Fiber | null,  // 下一个兄弟元素的Fiber
  return: Fiber | null,  // 父元素的Fiber
  // ...其他属性
}

单元工作+链接属性

  • 每个Fiber节点代表一个单元,所有Fiber节点共同组成一个Fiber链表树(有链接属性,同时又有树的结构),这种结构让React可以细粒度控制节点的行为。
  • childsibling 和 return 字段构成了Fiber之间的链接关系,使React能够遍历组件树并知道从哪里开始、继续或停止工作。

2.双缓冲机制

fiber同时维护两棵树,当前树和正在执行的树

React在更新时,会根据现有的Fiber树(Current Tree)创建一个新的临时树(Work-in-progress (WIP) Tree),WIP-Tree包含了当前更新受影响的最高节点直至其所有子孙节点

当前树是显示在页面上,而临时树在后台更新,等到更新完毕再复制其他节点,最终替换掉当前树,可实现平滑过渡

3.调度器

用来管理任务优先级,确保高优先级任务的及时执行

4.副作用链

completeUnitOfWork 负责遍历Fiber节点,同时记录了有副作用节点的关系,形成链表,等渲染后统一执行,确保副作用顺序和一致性

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐