react-fiber-前置知识

前言

这篇文章讲一下 react-fiber 的基本原理。会涉及到一些浏览器的机制,以及 react 与浏览器通信的小知识。


现如今,浏览器的刷新帧率基本都是 1 秒 60 帧,即:1 帧 = 1000ms / 60 ≈ 16.6ms。而在每一帧中,浏览器会做以下几件事:

  1. 接受输入事件:阻塞输入事件(touch,wheel)和非阻塞事件(click,keypress)等
  2. 执行事件回调 (JavaScript)
  3. 开始一帧
  4. 执行 RAF(RequestAnimationFrame)
  5. 计算样式,页面布局 (layout)
  6. 绘制渲染(paint)
  7. 空闲时间(可用 requestIdleCallback 申请时间片)

其中,前六个任务执行的时间一般约为 6ms 左右,意思就是浏览器平均每一帧大约能够留下 10ms 的时间为空余时间。而 react 正是利用每一帧的空余时间,来执行自己的任务。

  • 如果执行完一个任务后还有空余的时间且还有任务,则会继续执行。
  • 如果没有空余时间,则会将控制权交还给浏览器,使其进行下一帧任务。
    依次循环。

在每一帧的活动中,申请到的时间片为浏览器每一帧任务剩余的时(约 10ms),
当浏览器不需要执行任务(1-6)时,浏览器会将 50ms 左右的时间分给申请的时间片里,
以此达到尽快完成任务。
这里浏览器分配 50ms 的原因是:

  • 浏览器默认认为:100ms 延迟内用户感觉是流畅的,浏览器会在空余时间分配 1 秒 20 帧,即 1000 / 20 = 50ms。

react 会模拟 messageChannel 方法来与浏览器实现通信。从而达到申请调度到浏览器每一帧的空余时间
postMesage()(宏任务)在重绘之后进行,正好应证了 eventLoop 重绘之后浏览器进入空余时间。