六、Fiber架构的工作原理
00 min
2024-10-18
 
通过上一节的学习,我们了解了Fiber是什么,知道Fiber节点可以保存对应的DOM节点。
相应的,Fiber节点构成的Fiber树就对应DOM树。
那么如何更新DOM呢?这需要用到称之为“双缓存“的技术。
 

什么是”双缓存“


当我们用 canvas 绘制动画,每一帧绘制前都会调用 ctx.clearRect 清除上一帧的画面。
如果当前帧画面计算量比较大,导致清除上一帧画面到绘制当前帧画面之间有比较长的间隙,就会出现白屏。
为了解决这个问题,我们可以在内存中绘制当前帧动画,绘制完毕后直接替换掉上一帧画面,由于省去了两帧替换的计算时间,不会出现从白屏到出现画面闪烁情况。
这种在内存中构建并直接替换的技术叫做双缓存。
React 使用“双缓存”来完成 Fiber树 的构建与替换——对应着 DOM树 的创建与更新。
 

双缓存 Fiber 树


React最多会同时存在两颗 Fiber树。当前屏幕上显示内容对应的 Fiber树 称之为 current Fiber树,正在内存中构建的 Fiber树 称为 workInProgress Fiber 树
current Fiber树 中的 Fiber节点被称为 current fiber,workInProgress Fiber树 中的 Fiber节点 被称为 workInProgress fiber,他们通过 alternate 属性连接。
即当 workInProgress Fiber树 构建完成交给 Renderer 渲染在页面上后,应用根节点的 current 指针指向 workInProgress Fiber树,此时 workInProgress Fiber树 就变成了 current Fiber树
React 应用的根节点通过使 current 指针在不同的 Fiber树rootFiber 间切换来完成 current Fiber 树指向的切换。
即当 workInProgress Fiber树 构建完成交给 Renderer 渲染在页面上后,应用根节点的 current 指针指向 workInProgress Fiber树,此时 workInProgress Fiber树 就变成了 current Fiber树
每次状态更新都会产生新的 workInProgress Fiber树,通过 currentworkInProgress 的替换,完成 DOM 的更新。
接下来我们以具体例子讲解 mount时、update时 的构建/替换流程。
 

mount 时


考虑如下例子:
  1. 首次执行 ReactDOM.render 会创建 fiberRootNode(源码中叫做 fiberRoot)和 rootFiber。其中 fiberRootNode 是整个应用的根节点,rootFiber<App/> 所在组件树的根节点。
    1. 之所以要区分 fiberRootNoderootFiber,是因为在应用中我们可以多次调用 ReactDOM.render 渲染不同的组件树,他们会拥有不同的 rootFiber 。但是整个应用的跟节点只有一个,那就是 fiberRootNode
      fiberRootNode 的 current 会指向当前页面上已经渲染的内容对应的 Fiber树,即 current Fiber树。
      notion image
      由于是首屏渲染,页面中还没有挂载任何DOM,所有 fiberRootNode.current 指向的 rootFiber 没有任何子fiber节点(即current Fiber树 为空)。
       
  1. 接下来进入render阶段,根据组件返回的JSX在内存中依次创建Fiber节点并连接在一起构建Fiber树,被称为workInProgressFiber树。
    1. 在构建workInProgress Fiber树时会尝试复用current Fiber树中已有的Fiber节点内的属性,在首屏渲染时只有rootFiber存在对应的current Fiber(即rootFiber.alternate)
notion image
  1. 图中右侧已经构建完的 workInProgress Fiber树在commit阶段渲染到页面。
    1. 此时DOM更新为右侧树对应的样子。fiberRootNode的current指针指向workInProgress Fiber树使其变为current Fiber树。
      notion image
       
       

update 时


  1. 接下来我们点击 p节点 触发状态改变,这会开启一次新的 renderer阶段并构建一颗新的 workInProgress Fiber树。
    1. notion image
      和 mount 时一样,workInProgress fiber 的创建可以复用 current Fiber树对应的节点数据。
      这个决定是否服用的过程就是Diff算法,后面章节会详细讲解
       
  1. workInProgress Fiber树在renderer阶段完成构建后进入 commit阶段 渲染到页面上。完成渲染后,workInProgress Fiber树 变为 current Fiber树。
    1. notion image
 

总结


本文介绍了 Fiber树 的构建与替换过程。这个过程伴随着 DOM 的更新。
那么在构建过程中每个 Fiber节点具体是如何创建的?我们会在架构片的 render 阶段讲解。
上一篇
空白文章
下一篇
解密 React:探究背后的原理与源码