Fiber结构

514 阅读2分钟

fiber 的起源

因为react想要实现异步可中断更新的架构,之前的虚拟DOM就无法满足需求了。所以就全新设计了现在的Fiber架构。

fiber的含义

  1. 作为架构来说,老的架构采用递归方式进行更新,数据保存在递归的调用栈中,所以被称为stack Reconciler。现在新的架构中,更新是基于fiber节点所做的,所以被称为fiber reconciler。
  2. 作为静态数据结构来说,每个fiber节点对应一个react element,保存了该组件的类型(函数组件、类组件或者是原生组件),对应DOM节点等信息。
  3. 作为动态工作单元来说,每个fiber节点保存了本次更新中该组件改变的状态,要执行的工作(需要被删除、插入到页面或者被更新)。

所以依据第二点,一个fiber节点其实就对应着一个DOM节点,相应的,Fiber节点对应的fiber树也就是对应着DOM树了。既然在架构上统一起来了,那么现在是如何通过fiber来更新DOM的呢?这个技术就是我们需要理解的双缓存。

双缓存

当我们使用canvas绘制动画,每一帧都会在绘制前调用ctx.clearRect清除上一帧绘制的画面。如果当前帧计算量比较大,导致清除上一帧画面到绘制当前帧画面之间有较长的间隙,就会出现白屏。为了解决这个问题,我们可以在内存中绘制当前帧的动画,当绘制完成后直接用当前帧替换上一帧的画面,由于省去了两帧替换间的时间,就不会出现白屏到画面出现的闪烁现象。这种在内存中构建并直接替换的技术就是双缓存。

react利用双缓存技术进行Fiber树的构建和更新--也就是对应DOM树的构建和更新。

双缓存fiber树

  1. current Fiber,当前屏幕上显示的内容对应的fiber树;
  2. workInProgress Fiber,正在内存中构建的fiber. 相应的,两棵树中的fiber节点就被称为相应的节点,他们通过alternate。 currentFiber.alternate===workInProgressFiber workInProgressFiber.alternate===currentFiber

React应用的根节点通过使current指针在不同的Fiber树的rootFiber间切换current fiber树指向的切换。

当workInProgress Fiber树构建完成交给renderer渲染在页面上后,页面根节点current指针就会指向workInProgress,它就变成新的current fiber树了。

每次状态更新都会产生新的workInProgress树,通过current与workInProgress的替换,完成DOM更新。

todo:

  1. fiber在调度中的作用。
  2. fiber在reconciler中的作用。
  3. fiber在renderer中的作用。
  4. fiber在hook中的作用。