Code Play Games

Login

Register

Why requestAnimationFrame is Essential for HTML5 Game Performance

If you're building games with JavaScript, requestAnimationFrame (rAF) is the most important function you need to know. It’s the secret sauce behind smooth, efficient animations—and using it correctly can make or break your game’s performance.

In this post, we’ll explore:
✔ What requestAnimationFrame does
✔ Why it’s better than setInterval or setTimeout
✔ How to use it in your game loop
✔ Common mistakes to avoid


1. What is requestAnimationFrame?

requestAnimationFrame is a browser API designed specifically for smooth animations and games. Instead of running at arbitrary intervals (like setInterval), it syncs with your monitor’s refresh rate (usually 60Hz, meaning 60 FPS).

Basic Syntax

function gameLoop(timestamp) {
  // Game logic & rendering here
  requestAnimationFrame(gameLoop); // Schedule next frame
}

// Start the game loop
requestAnimationFrame(gameLoop);

2. Why Use rAF Instead of setInterval or setTimeout?

Feature requestAnimationFrame setInterval/setTimeout
Framerate Matches display refresh rate (smooth) Fixed interval (can stutter)
Battery Efficiency Pauses in background tabs Keeps running, wasting CPU
Jank Prevention Avoids frame drops by syncing with GPU Can cause missed frames
Automatic Delta Time Provides a high-res timestamp Requires manual timing

Key Advantages of rAF:

✅ Smoother gameplay – No tearing or skipped frames
✅ More efficient – Doesn’t run when the tab is hidden
✅ Built for animations – Optimized by browsers


3. How to Use rAF in a Game Loop

A proper game loop should:

  1. Track time between frames (delta time)

  2. Update game logic (physics, input, AI)

  3. Render the frame

 
let lastTime = 0;

function gameLoop(timestamp) {
  // Calculate delta time (seconds since last frame)
  const deltaTime = (timestamp - lastTime) / 1000;
  lastTime = timestamp;

  // Update game state (movement, collisions, etc.)
  update(deltaTime);

  // Draw everything
  render();

  // Repeat
  requestAnimationFrame(gameLoop);
}

// Start the game
requestAnimationFrame(gameLoop);

Why Delta Time Matters

Without it, your game would run faster on high-refresh-rate monitors and slower on old devices. Delta time ensures consistent speed across all hardware.


4. Common Mistakes (And How to Fix Them)

❌ Mistake 1: Not Using Delta Time

Bad:

player.x += 5; // Speed depends on framerate

Good:

player.x += 5 * deltaTime; // Speed is consistent

❌ Mistake 2: Running Logic When Tab is Hidden

Fix:

if (!document.hidden) {
  update(deltaTime); // Only run when visible
}

❌ Mistake 3: Forgetting to Cancel rAF

If your game has screens (menu, pause), always cancel the loop:

let animationId;

function startGame() {
  animationId = requestAnimationFrame(gameLoop);
}

function pauseGame() {
  cancelAnimationFrame(animationId);
}

5. When Should You Not Use rAF?

While requestAnimationFrame is ideal for rendering, avoid it for:

  • Non-visual logic (use Web Workers instead)

  • Network requests (use setTimeout or Promises)

  • Heavy computations (can block rendering)


Conclusion: Why rAF Wins

If you want buttery-smooth gameplayrequestAnimationFrame is the only correct choice. It’s:
🔥 Optimized for animations
🔋 Battery-friendly
⏱️ Precision-timed

Try it in your next game! For a complete example, check out:
Basic Game Scaffold on GitHub


Bonus: Quick Comparison

requestAnimationFrame setInterval
✅ Syncs with display ❌ Fixed interval
✅ Efficient ❌ Wastes CPU
✅ Smooth animations ❌ Can stutter

 

Back to Posts