【study】requestAnimationFrame是什么?

70 阅读2分钟
1、含义:
  • requestAnimationFrame 是一种用于动画性能优化的浏览器原生方法,它告诉浏览器你希望执行一个动画,并在下一次重绘之前调用指定的回调函数。这使你可以在每一帧上执行动画,而不是使用传统的 setTimeout 或 setInterval 来更新动画,从而实现更流畅的动画效果和更高的性能。
2、主要优势
  1. 高效的动画执行requestAnimationFrame 让浏览器在刷新屏幕时同步执行动画更新。这意味着动画会与屏幕刷新频率一致(通常是 60 次每秒,但具体频率由硬件决定),从而实现更流畅的动画效果。
  2. 智能帧合并:如果页面在后台标签页中或者被隐藏,requestAnimationFrame 会暂停动画执行,以节省 CPU 和电池资源。而 setTimeout 和 setInterval 则继续运行,不管页面是否在前台。
  3. 浏览器优化:浏览器可以优化内部流程,使得动画执行更加顺畅和高效
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>

输出顺序

  1. Script start
  2. Script end
  3. Promise
  4. setTimeout
  5. requestAnimationFrame
5、总结
  • requestAnimationFrame 是浏览器提供的用于优化动画帧调度的 API,不属于宏任务或微任务。
  • 它的回调会在浏览器重绘之前执行,与浏览器的刷新周期同步。
  • 在事件循环中,它会在所有宏任务和微任务完成之后执行,以确保动画的流畅度和性能。