当机器性能不足以维持高帧数渲染时,一个较低的稳定的帧数相比不断在60帧上下波动能带来更好的体验。所以在一些动画交互较多的场景,有必要限制渲染帧数。

class AnimationFrame {
  constructor(fps = 60, animate) {
    this.requestID = 0;
    this.fps = fps;
    this.animate = animate;
  }

  start() {
    let then = performance.now();
    const interval = 1000 / this.fps;
    const tolerance = 0.1;

    const animateLoop = (now) => {
      this.requestID = requestAnimationFrame(animateLoop);
      const delta = now - then;

      if (delta >= interval - tolerance) {
        then = now - (delta % interval);
        this.animate(delta);
      }
    };
    this.requestID = requestAnimationFrame(animateLoop);
  }

  stop() {
    cancelAnimationFrame(this.requestID);
  }
}

requestAnimationFrame永远以60FPS运行,也就是每16.6ms执行一次,以我们要限制在10FPS(100ms)为例。递归7次时116.2ms>100ms,我们再执行下一次渲染。为了避免误差导致整体帧数低于设置,这里不能直接使用then = now,而是 then = now - (delta % interval)

See the Pen Limiting FPS (framerate) with Request Animation Frame by Rishabh (@rishabhp) on CodePen.

参考文章:
Controlling the Frame Rate with requestAnimationFrame
limitLoop.js