一般浏览器的刷新率为 60HZ,即 1 秒钟刷新 60 次。1000ms / 60hz = 16.6
,大概每过 16.6ms 浏览器会渲染一帧画面。
在这段时间内,浏览器大体会做两件事:task
与 render
。
task -> requestAnimationFrame -> render -> requestIdleCallback
如果渲染完成后还有空闲时间,则 requestIdleCallback API 会被调用。
如果 task
执行时间超过了 16.6ms
(比如 task
中有个很耗时的 while
循环)。
那么这一帧就没有时间 render
,页面直到下一帧 render
后才会更新。表现为页面卡顿一帧,或者说掉帧。
最好的办法是时间切片,把长时间 task
分割为几个短时间 task
。
为了解决掉帧造成的卡顿,React16 将递归的构建方式改为可中断的遍历。React16 就是基于 requestIdleCallbackAPI,实现了自己的 Fiber Reconciler。
以 5ms
的执行时间划分 task
,每遍历完一个节点,就检查当前 task
是否已经执行了 5ms
。
如果超过 5ms
,则中断本次 task
。
通过将 task
执行时间切分为一个个小段,减少长时间 task
造成无法 render
的情况,这就是时间切片。