1、含义:
requestAnimationFrame是一种用于动画性能优化的浏览器原生方法,它告诉浏览器你希望执行一个动画,并在下一次重绘之前调用指定的回调函数。这使你可以在每一帧上执行动画,而不是使用传统的setTimeout或setInterval来更新动画,从而实现更流畅的动画效果和更高的性能。
2、主要优势
- 高效的动画执行:
requestAnimationFrame让浏览器在刷新屏幕时同步执行动画更新。这意味着动画会与屏幕刷新频率一致(通常是 60 次每秒,但具体频率由硬件决定),从而实现更流畅的动画效果。 - 智能帧合并:如果页面在后台标签页中或者被隐藏,
requestAnimationFrame会暂停动画执行,以节省 CPU 和电池资源。而setTimeout和setInterval则继续运行,不管页面是否在前台。 - 浏览器优化:浏览器可以优化内部流程,使得动画执行更加顺畅和高效
3、代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>requestAnimationFrame Example</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
const box = document.getElementById('box');
let start = null;
function step(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
box.style.transform = 'translateX(' + Math.min(progress / 10, 200) + 'px)';
if (progress < 2000) { // 2 seconds
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
</script>
</body>
</html>
4、requestAnimationFrame是宏任务还是微任务?
requestAnimationFrame既不是宏任务(macrotask)也不是微任务(microtask)。它属于浏览器的渲染步骤,专门用于优化动画的帧调度。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>requestAnimationFrame Example</title>
</head>
<body>
<script>
console.log("Script start");
setTimeout(() => {
console.log("setTimeout"); // 宏任务
}, 0);
Promise.resolve().then(() => {
console.log("Promise"); // 微任务
});
requestAnimationFrame(() => {
console.log("requestAnimationFrame"); // 渲染任务
});
console.log("Script end");
</script>
</body>
</html>
输出顺序
Script startScript endPromisesetTimeoutrequestAnimationFrame
5、总结
requestAnimationFrame是浏览器提供的用于优化动画帧调度的 API,不属于宏任务或微任务。- 它的回调会在浏览器重绘之前执行,与浏览器的刷新周期同步。
- 在事件循环中,它会在所有宏任务和微任务完成之后执行,以确保动画的流畅度和性能。