• 主页

  • 投资

  • IT

    🔥
  • 设计

  • 销售

  • 共299篇

    前端 - Javascript

关闭

返回栏目

关闭

返回前端 - Javascript栏目

157 - 定时器 - requestAnimationFrame - 动画帧定时器的优势

作者:

贺及楼

成为作者

更新日期:2025-02-21 20:11:59

定时器 - requestAnimationFrame - 动画帧定时器的优势

在前端开发中,实现动画效果是一项常见的需求。为了实现流畅的动画,我们常常需要借助定时器。JavaScript 中传统的定时器有 setTimeoutsetInterval,而 HTML5 引入了一个新的定时器函数 requestAnimationFrame。本文将深入探讨 requestAnimationFrame 作为动画帧定时器的优势。

传统定时器的局限性

在介绍 requestAnimationFrame 之前,我们先来看看传统定时器 setTimeoutsetInterval 在实现动画时存在的问题。

1. 执行时机不稳定

setTimeoutsetInterval 是基于时间来触发回调函数的。然而,JavaScript 是单线程执行的,当主线程有其他耗时任务时,定时器的回调函数可能会被延迟执行。例如:

  1. function expensiveTask() {
  2. let sum = 0;
  3. for (let i = 0; i < 1000000; i++) {
  4. sum += i;
  5. }
  6. console.log('Expensive task finished');
  7. }
  8. setTimeout(() => {
  9. console.log('Timer callback executed');
  10. }, 100);
  11. expensiveTask();

在这个例子中,由于 expensiveTask 是一个耗时任务,setTimeout 的回调函数可能会在 100ms 之后很久才执行,这就会导致动画的帧率不稳定。

2. 高 CPU 占用

当使用 setInterval 来实现动画时,即使页面处于不可见状态(如切换到其他标签页),定时器依然会按照设定的时间间隔不断执行回调函数,这会导致不必要的 CPU 资源浪费。

requestAnimationFrame 的优势

requestAnimationFrame 是专门为实现动画效果而设计的定时器,它具有以下显著优势:

1. 与浏览器刷新频率同步

浏览器的刷新频率通常是 60Hz,即每秒刷新 60 次,每次刷新的间隔约为 16.7ms。requestAnimationFrame 会根据浏览器的刷新频率来执行回调函数,确保动画的帧率稳定在 60fps(帧每秒)左右,从而实现流畅的动画效果。例如:

  1. const element = document.getElementById('myElement');
  2. let position = 0;
  3. function animate() {
  4. position++;
  5. element.style.left = position + 'px';
  6. requestAnimationFrame(animate);
  7. }
  8. requestAnimationFrame(animate);

在这个例子中,animate 函数会在每次浏览器刷新时被调用,不断更新元素的位置,实现平滑的移动动画。

2. 自动优化性能

当页面处于不可见状态时,requestAnimationFrame 会自动暂停执行,从而节省 CPU 资源。例如,当用户切换到其他标签页时,动画会自动停止,直到用户切换回当前页面。这使得页面在不同的使用场景下都能保持良好的性能。

3. 精准的时间控制

requestAnimationFrame 的回调函数会传入一个时间戳参数,该时间戳表示当前帧开始的时间。通过这个时间戳,我们可以实现更加精准的动画控制。例如:

  1. const element = document.getElementById('myElement');
  2. let startTime;
  3. function animate(timestamp) {
  4. if (!startTime) {
  5. startTime = timestamp;
  6. }
  7. const elapsedTime = timestamp - startTime;
  8. const position = Math.sin(elapsedTime / 1000) * 100;
  9. element.style.left = position + 'px';
  10. requestAnimationFrame(animate);
  11. }
  12. requestAnimationFrame(animate);

在这个例子中,我们根据动画开始以来的 elapsedTime 来计算元素的位置,实现了一个正弦曲线的动画效果。

总结

特性 setTimeout/setInterval requestAnimationFrame
执行时机 不稳定,受主线程任务影响 与浏览器刷新频率同步,稳定
CPU 占用 页面不可见时仍继续执行,浪费资源 页面不可见时自动暂停,节省资源
时间控制 基于固定时间间隔,不够精准 提供时间戳参数,可实现精准控制

综上所述,requestAnimationFrame 在实现动画效果方面具有明显的优势。在开发前端动画时,我们应该优先考虑使用 requestAnimationFrame 来替代传统的定时器,以获得更加流畅、高效的动画体验。