页面是一帧一帧绘制出来的,当每秒绘制的帧数(FPS)达到 60 时,页面是流畅的,小于这个值时,用户会感觉到卡顿。
1s 60帧,所以每一帧分到的时间是 1000/60 ≈ 16 ms。所以我们书写代码时力求不让一帧的工作量超过 16ms。
Frame那么浏览器每一帧都需要完成哪些工作?
浏览器一帧内的工作
通过上图可看到,一帧内需要完成如下六个步骤的任务:
处理用户的交互
JS 解析执行
帧开始。窗口尺寸变更,页面滚去等的处理
rAF
布局
绘制
requestIdleCallback上面六个步骤完成后没超过 16 ms,说明时间有富余,此时就会执行 requestIdleCallback 里注册的任务。
requestIdleCallback 在浏览器一帧内的位置示意
从上图也可看出,和 requestAnimationFrame 每一帧必定会执行不同,requestIdleCallback 是捡浏览器空闲来执行任务。
如此一来,假如浏览器一直处于非常忙碌的状态,requestIdleCallback 注册的任务有可能永远不会执行。此时可通过设置 timeout (见下面 API 介绍)来保证执行。
APIvar handle = window.requestIdleCallback(callback[, options])