学习目标
了解屏幕刷新率,下面这些 API 的基础用法及执行时机。从浏览器 Performance 面板中看每一帧的执行时间以及工作。探索哪些 API 适合用来调度任务
- requestAnimationFrame
- requestIdleCallback
- setTimeout
- MessageChannel
- 微任务* MutationObserver* Promise
屏幕刷新率
- 目前大多数设备的屏幕刷新率为 60 次/秒
- 页面是一帧一帧绘制出来的,当每秒绘制的帧数(FPS)达到 60 时,页面是流畅的,小于这个值时,用户会感觉到卡顿
- 每帧的预算时间是 16.66 毫秒(1 秒/60),因此在写代码时,注意避免一帧的工作量超过 16ms。在每一帧内,浏览器都会执行以下操作:* 执行宏任务、用户事件等。* 执行 requestAnimationFrame* 执行样式计算、布局和绘制。* 如果还有空闲时间,则执行 requestIdelCallback* 如果某个任务执行时间过长,则当前帧不会绘制,会造成掉帧的现象。
- 显卡会在每一帧开始时间给浏览器发送一个 vSync 标记符,从而让浏览器刷新频率和屏幕的刷新频率保持同步。
以下面的例子为例:
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><title>Frame</title><metaname="viewport"content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"/><style> #animation {width: 30px;height: 30px;background: red;animation: myfirst 5s infinite;}@keyframes myfirst {from {width: 30px;height: 30px;border-radius: 0;background: red;}to {width: 300px;height: 300px;border-radius: 50%;background: yellow;}} </style></head><body><div id="animation">test</div></body><script> function rafCallback(timestamp) {window.requestAnimationFrame(rafCallback);}window.requestAnimationFrame(rafCallback);function timeoutCallback() {setTimeout(timeoutCallback, 0);}setTimeout(timeoutCallback, 0);const timeout = 1000;requestIdleCallback(workLoop, { timeout });function workLoop(deadline) {requestIdleCallback(workLoop, { timeout });const start = new Date().getTime();while (new Date().getTime() - start < 2) {