ReviseAlgo Logo

Asynchronous JavaScript

setTimeout, setInterval, requestAnimationFrame

Master scheduling timing in JavaScript. Contrast setTimeout, setInterval, and requestAnimationFrame in terms of execution loop alignment and screen refresh sync.

Last Updated: July 15, 2026 10 min read

1. Introduction

JavaScript provides timers to schedule tasks to run in the future: setTimeout (one-time execution), setInterval (recurring execution), and requestAnimationFrame (execution aligned with screen refresh cycles).

2. Why It Matters

Using the wrong timing method can cause problems. For example, using setInterval for animations can cause stuttering, while using setTimeout for UI changes can cause visual tearing if the code runs out of sync with the screen's refresh rate.

3. Real-World Analogy

Think of a Theater Production Stage Manager:

  • setTimeout (Timed Cue): "Wait 5 seconds, then drop the curtain once." The action is scheduled to run after a delay.
  • setInterval (Timed Repeater): "Flash the strobe light every 2 seconds, indefinitely." The action runs repeatedly at set intervals.
  • requestAnimationFrame (Conductor Sync): "Only step onto the stage when the spotlights are aligned and the cameras are recording a new frame." The action is synchronized with the production's visual layout, ensuring a smooth presentation.

4. Timers and Animation Scheduling

Let's explore the syntax and behavior of the three APIs:

1. setTimeout & setInterval:

Standard macro-scheduling timers. They are not guaranteed to run at exact times; they are delayed if the Call Stack is busy.

2. requestAnimationFrame (rAF):

Schedules callbacks to run immediately before the browser performs a repaint cycle (usually 60 times per second, or matching the screen's refresh rate). Unlike timers, requestAnimationFrame automatically pauses when the browser tab is inactive, saving battery and CPU cycles.

5. Comparison Summary

API Execution Alignment Stops when tab is inactive? Primary Use Case
setTimeout Callback Queue (Event Loop tick) No (throttled to 1s in some browsers) One-time deferred tasks
setInterval Callback Queue (Event Loop tick) No (throttled to 1s) Recurring non-UI updates (e.g. data polling)
requestAnimationFrame Repaint Queue (Screen Refresh rate) Yes (automatically paused) Smooth UI animations and rendering loops

6. Practical Example

This script demonstrates implementing a countdown timer that stops automatically when it reaches zero:

7. Common Mistakes

  • Overlapping setInterval ticks: If the callback execution takes longer than the interval delay, the callbacks queue up, executing back-to-back with no delay. Use recursive setTimeout instead to ensure there is a constant delay between executions.

8. Quick Quiz

Q1: Which scheduling API automatically pauses execution when the browser tab is hidden or minimized?

A) setInterval

B) requestAnimationFrame

Answer: B — requestAnimationFrame pauses execution when the tab is inactive to optimize performance and save battery power.

9. Scenario-Based Challenge

The Smooth Slider Component:

You are building an image slider animation. If you use setInterval(move, 16), users experience visual stuttering on 120Hz screens. Explain why switching to requestAnimationFrame resolves the stuttering issue across different screens.

10. Debugging Exercise

Identify the nesting stack overflow bug in this recursive timer:

function animateBox() {
  const el = document.getElementById('item');
  el.style.left = (parseInt(el.style.left) || 0) + 1 + 'px';

// Bug: calling requestAnimationFrame requires passing the function reference! requestAnimationFrame(animateBox()); // crashes with stack overflow! }

View Solution

Diagnosis: The code invokes animateBox() immediately during the requestAnimationFrame registration call, causing infinite synchronous recursion and a stack overflow.

Fix: Pass the function reference itself without invoking it:

requestAnimationFrame(animateBox); // Pass function reference

11. Interview Questions

🟢 Q1: Why is requestAnimationFrame better than setTimeout or setInterval for rendering UI animations?

Answer:
1. Screen Refresh Sync: requestAnimationFrame is synchronized with the browser's repaint cycle, ensuring animations match the screen's refresh rate (e.g. 60Hz, 90Hz, 120Hz) without skipped frames.
2. Throttling: The browser automatically pauses requestAnimationFrame animations when the tab is inactive, reducing CPU usage and saving battery. Timers continue to run in the background.
3. Rendering Optimization: The browser groups all requestAnimationFrame DOM updates into a single repaint flow, reducing layout thrashing.

12. Production Considerations

  • Cleanup Resources: Always clean up active timers (using clearTimeout or clearInterval) in component teardown phases (like React's useEffect cleanup returns) to prevent memory leaks and unexpected background activity.