前端 requestAnimationFrame使用场景,执行时机,性能问题

735 阅读3分钟

requestAnimationFrame 是一个用于在浏览器的下一次重绘之前调用指定回调函数的方法。它被广泛用于实现平滑的动画效果。下面我们详细讲解一下它的使用场景、执行时机、性能问题以及代码示例。

使用场景

  1. 动画requestAnimationFrame 是实现平滑动画的最佳选择。它确保动画在浏览器的刷新频率(通常是60次每秒)下运行,避免了使用 setTimeoutsetInterval 可能带来的卡顿和不一致性。
  2. 滚动事件:在滚动事件中使用 requestAnimationFrame 来处理滚动相关的操作(如懒加载、无限滚动等),可以避免频繁的 DOM 操作导致的性能问题。
  3. 游戏开发:在游戏开发中,requestAnimationFrame 用于实现游戏循环,以确保游戏在每一帧都能更新和渲染。

执行时机

requestAnimationFrame 会在浏览器下一次重绘之前调用指定的回调函数。这意味着回调函数会在浏览器进行布局和绘制操作之前执行,从而确保动画和其他视觉效果的流畅性。

性能问题

requestAnimationFrame 相对于 setTimeoutsetInterval 有以下几个性能优势:

  1. 节省资源:在后台标签页或隐藏的 iframe 中,requestAnimationFrame 会暂停调用回调函数,从而节省资源。
  2. 更平滑的动画requestAnimationFrame 的调用频率与屏幕刷新率同步(通常为每秒60次),这使得动画更加平滑。
  3. 避免丢帧requestAnimationFrame 确保在每一帧进行一次 DOM 操作,避免了频繁的 DOM 操作导致的丢帧现象。

代码示例

基本用法

function animate() {
  // 在这里执行动画相关的代码
  console.log('Animating...');
  // 请求下一帧
  requestAnimationFrame(animate);
}

// 开始动画
requestAnimationFrame(animate);

平滑动画示例

下面是一个使用 requestAnimationFrame 实现平滑动画的示例:

<!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;
      top: 0;
      left: 0;
    }
  </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) {
        requestAnimationFrame(step);
      }
    }

    // 开始动画
    requestAnimationFrame(step);
  </script>
</body>
</html>

在这个示例中,我们将一个红色方块从左上角移动到右侧。每次调用 step 函数时,我们计算自动画开始以来的时间,并根据这个时间来更新方块的位置。

滚动事件优化

使用 requestAnimationFrame 优化滚动事件处理:

let ticking = false;

function onScroll() {
  if (!ticking) {
    requestAnimationFrame(() => {
      // 在这里处理滚动事件
      console.log('Scrolling...');
      ticking = false;
    });
    ticking = true;
  }
}

window.addEventListener('scroll', onScroll);

在这个示例中,我们使用 requestAnimationFrame 来限制滚动事件处理的频率,从而避免频繁的 DOM 操作导致的性能问题。

requestAnimationFrame 是前端开发中实现平滑动画和优化性能的强大工具。通过合理使用 requestAnimationFrame,我们可以确保动画和其他视觉效果在浏览器中流畅运行,同时避免不必要的性能损耗。