requestAnimationFrame 与 setInterval
Jan 05, 2022
# Browser
# requestAnimationFrame
window.requestAnimationFrame()
要求浏览器在下次重绘之前调用指定的回调函数更新动画。如果想在浏览器下一次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()
。
js
// requestAnimationFrame
const el = document.getElementById("box");
let start;
function step(timestamp) {
if (start === undefined) start = timestamp;
const elapsed = timestamp - start;
// 这里使用`Math.min()`确保元素刚好停在200px的位置
el.style.transform = `translateX(${Math.min(0.1 * elapsed, 200)}px)`;
if (elapsed < 2000) { // 两秒后停止动画
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
# setInterval
js
// setInterval
const el = document.getElementById('box');
let px = 0;
let t = null
function step () {
px++;
el.style.transform = `translateX(${ px }px)`;
if (px >= 200) {
clearInterval(t);
}
}
t = setInterval(step, 1000 / 60);
# 两者对比
- 布局绘制逻辑不同
- setInterval:回调逻辑存在多次 DOM 操作,就会进行多次计算、绘制
- requestAnimationFrame:把所有DOM 操作集中起来,一次性进行统一计算、统一绘制,性能较好
- 窗口最小化时,运行情况不同
- setInterval:一直执行回调函数
- requestAnimationFrame:最小化时,暂停程序执行;页面打开时,从暂停的位置重新开始
- 是否导致无意义的回调执行,重绘重排
- setInterval(step, 0):导致多次无意义的回调执行(计时间隔小于刷新率,无意义)
- requestAnimationFrame:只会在下次重绘时执行