Complete Guide to requestAnimationFrame

Introduction

Overview

requestAnimationFrame is a browser API that tells the browser you wish to perform an animation and requests that the browser calls a specified callback function before the next repaint.

Note: This API helps synchronize your animations with the browser's refresh rate, improving performance and battery life.

Basic Usage

Syntax & Flow

To start an animation loop, define a callback that updates your animation state and then calls requestAnimationFrame again with itself:

function animate(timestamp) {
    // Update animation state using the timestamp
    drawFrame(timestamp);
    requestAnimationFrame(animate);
}

// Start the loop
requestAnimationFrame(animate);

The timestamp parameter is a DOMHighResTimeStamp indicating the exact time when the callback starts.

Canceling Animations

Stopping the Loop

Use cancelAnimationFrame with the ID returned by requestAnimationFrame to stop the loop:

let frameId = requestAnimationFrame(animate);

// Later...
cancelAnimationFrame(frameId);

Note: Always cancel unused frames to prevent memory leaks and unnecessary CPU use.

Browser Support & Polyfills

Ensuring Compatibility

Most modern browsers natively support this API. For older browsers, include a polyfill:

// Polyfill for older browsers
if (!window.requestAnimationFrame) {
    window.requestAnimationFrame =
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function(callback) {
            return setTimeout(() => callback(Date.now()), 1000 / 60);
        };
    window.cancelAnimationFrame =
        window.cancelAnimationFrame ||
        window.mozCancelAnimationFrame ||
        function(id) {
            clearTimeout(id);
        };
}

Performance Considerations

Best Practices

Practical Example

Bouncing Ball on Canvas

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let x = 50, y = 50, vx = 2, vy = 3;

function draw(timestamp) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(x, y, 20, 0, Math.PI * 2);
    ctx.fill();

    x += vx;
    y += vy;
    if (x < 20 || x > canvas.width - 20) vx = -vx;
    if (y < 20 || y > canvas.height - 20) vy = -vy;

    requestAnimationFrame(draw);
}

requestAnimationFrame(draw);

Common Pitfalls

Avoid These Mistakes

Conclusion

Summary

requestAnimationFrame is the go-to API for efficient, smooth animations in the browser, syncing updates with display refresh rates and conserving resources in inactive tabs.