【react】16.6ms 的讨论

23 阅读2分钟

16.6ms

浏览器60hz刷新率,如果想让页面流畅,即 一秒 绘制 60 帧。 也就是 有16.6ms来绘制一帧只要保证 16.6ms能绘制出一帧,页面就不会卡顿.

但是页面绘制可能不需要16.6ms,剩余时间就可以干别的事情

60Hz 显示器 为例:

  • 屏幕每 16.6ms 刷新一次(也叫一次 VSync 垂直同步信号)。
  • 浏览器必须在下一个刷新信号到来前,准备好一张完整的新画面(Frame)。
  • 如果没准备好,屏幕就会复用上一帧的图像

结果:

用户看到的画面没有变化 → 就是“卡了一下”或者“掉帧(Dropped Frame)”。

本来是一秒60帧画面现在可能变成1秒40帧,所以就出现了卡顿


🧩 二、用通俗比喻来理解

你可以把显示器想成一个节拍器,每 16.6ms 打一下拍子:

咚——咚——咚——咚——

而浏览器要在每个“咚”到来之前,把下一张画做好交上去。

  • 如果画完及时交上去 ✅ → 一切流畅
  • 如果画太慢还没交 🕐 → 节拍器照样打 → 这次只能显示上一张画 ❌

于是用户看到的画面停顿了 1 帧甚至多帧。


⏱ 三、时间线形象示意

|<---- 16.6ms ---->|<---- 16.6ms ---->|<---- 16.6ms ---->|
 显示器刷帧#1         显示器刷帧#2         显示器刷帧#3
   ↑                      ↑                    ↑
 React/浏览器要在这之前准备好画面

假设第二帧计算太慢用了 25ms:

|<----16.6ms---->|<----16.6ms---->|<----16.6ms---->|
 [帧#1绘制]   [帧#2还没好,显示旧帧]   [帧#3更新]

→ 屏幕跳过了帧#2
→ 实际帧率变成 30FPS(甚至更低)
→ 肉眼就感到“卡顿”。


⚙️ 四、延伸:React / 浏览器怎么应对

为了不让 JS 阻塞绘制:

  • 浏览器用 requestAnimationFrame 保证绘制时机刚好卡在每帧开始前;
  • React Fiber 把渲染任务切片分阶段执行;
  • React 18 的 startTransition()useTransition() 允许延迟非紧急更新。

目的都是:

在 16.6ms 的时间预算里,
先保证**画面流畅(优先级高)** ,
再去做逻辑更新(优先级低)


✅ 总结一句话:

是的,16.6ms 内必须准备好新的一帧。

超过这个时间,就会错过显示器的刷新信号,
屏幕只能显示旧帧 → 发生掉帧 → 用户感觉“卡”。