I finally understand requestAnimationFrame

I finally understand requestAnimationFrame

Explaining requestAnimationFrame

I knew requestAnimationFrame was a Web API that helps smooth out the animations. But I never really understood the why.

How browser rendering works:

Browser has to paint pixels to the screen many times per second. This is called the "frame rate". You may have heard of 60 FPS. Frames per second. The browser paints pixels to the screen 60 times per second. Each frame needs to be calculated and drawn within ~16.7ms (1000ms/60fps). This involves several steps: JavaScript → Style calculations → Layout → Paint → Composite.

With this already, you might be able to understand the issue.

Let's dive into an example where ball animation is updated with setInterval:

const ball = document.querySelector(".ball");
let position = 0;

function updateBallPosition() {
  position += 5;
  ball.style.transform = `translateX(${position}px)`;
}

// BAD: Using setInterval
setInterval(updateBallPosition, 16); // trying to match 60fps

This is bad because even though we're trying to match 60fps, it will never be precise. By precise, I don't just mean 16.7ms but also WHEN precisely the next frame is going to be painted.

In human words, requestAnimationFrame is like saying "Hey browser, please call me right before you paint the next frame. I need to update the position of the ball here." If we don't do this, the browser might paint the next frame while we're still updating the ball's position.

This is what's causing the ball to jitter. It may look like it's "lagging" or "jumping".

FPS explained

FPS means frame per second. The reason we see things moving on a screen is because the browser is painting an entirely new image. It’s not actually moving. Throughout a single second, each frame is a completely new image drawn on the screen.

The lower the FPS, the more gap between the motions before we draw the next frame on the screen.

40 FPS timeline:
0ms    [Frame 1]
25ms   [Frame 2]
50ms   [Frame 3]
75ms   [Frame 4]

100 FPS timeline:
0ms    [Frame 1]
10ms   [Frame 2]
20ms   [Frame 3]
30ms   [Frame 4]

To know how many frames will be drawn per second, simply divide the number with 1000ms. Think of a ball moving. It’s much more smoother if the FPS higher.

The amount of FPS depends on your screen (read about Hz below).

And yes, the higher FPS requires more compute because of the steps the browser has to go through when drawing each image on the screen:

  1. Run JavaScript (process any animations/changes)

  2. Calculate layout (figure out where everything goes)

  3. Paint (determine what colors each pixel should be)

  4. Composite (combine all layers into final image)

  5. Send to display

Hertz

Hz (Hertz) is a unit that measures cycles per second. For screens, Hz indicates how many times the screen can refresh its image each second.

My ultra wide LG screen has 80 Hz for example. If you’re into gaming e.g. CS:GO, 144hz if not 240hz are great.

Hz is the phyiscal limit of the screen. If you’ve a 144hz monitor but your game says 300FPS, the reality is your computer could run 300FPS, but the physical limit will always be 144FPS.