Skip to content
intermediatePhase 33 · Advanced JavaScript

Macrotasks

Learn setTimeout, setInterval, and how macrotasks are scheduled.

30m
0 problems
Topic Progress0%

setTimeout and setInterval

setTimeout and setInterval are the most common macrotask creators.

setTimeout

Schedules a function to run after a specified delay.

console.log('Start');

setTimeout(() => {
  console.log('Timeout');
}, 1000);

console.log('End');
// Output: Start, End, Timeout (after 1 second)

Important: The delay is a minimum, not a guarantee. The callback won't run until:

  1. The specified time has elapsed
  2. The call stack is empty
  3. All microtasks have been processed
// Even with 0ms, it doesn't run immediately
setTimeout(() => console.log('timeout'), 0);
console.log('sync');
// Output: sync, timeout

setInterval

Repeats a function at specified intervals.

let count = 0;
const interval = setInterval(() => {
  console.log(`Count: ${count}`);
  count++;
  if (count > 5) {
    clearInterval(interval); // Stop after 5
  }
}, 1000);

Timing Issues

// setInterval doesn't wait for callback to finish
setInterval(() => {
  // If this takes 200ms, next fires at 1000ms (not 1200ms)
  console.log('tick');
}, 1000);

// Better: use setTimeout recursively
function repeat() {
  console.log('tick');
  setTimeout(repeat, 1000); // Waits for callback to finish
}
repeat();

Task Scheduling

JavaScript provides several ways to schedule tasks for later execution.

setTimeout(fn, 0)

Defers execution until the call stack is empty.

// Useful for breaking up long-running tasks
function processData(data) {
  // Process first batch synchronously
  processBatch(data.slice(0, 100));
  
  // Defer remaining batches
  setTimeout(() => {
    processBatch(data.slice(100, 200));
    setTimeout(() => {
      processBatch(data.slice(200));
    }, 0);
  }, 0);
}

requestAnimationFrame

Fires before the next browser paint.

function animate() {
  // Update animation
  element.style.left = `${x}px`;
  x++;
  
  if (x < 100) {
    requestAnimationFrame(animate); // ~60fps
  }
}
requestAnimationFrame(animate);

Comparison

Method Queue Priority Use Case
setTimeout Macrotask Low General deferral
setInterval Macrotask Low Repeated execution
requestAnimationFrame Macrotask Before paint Animations
queueMicrotask Microtask High Immediate post-sync

Preventing Starvation

// Bad: can starve macrotasks
function heavyTask() {
  // Process items
  processItems();
  queueMicrotask(heavyTask); // Keeps adding microtasks
}

// Good: yield to macrotasks
function heavyTask() {
  processItems();
  setTimeout(heavyTask, 0); // Allows macrotasks to run
}

Rendering and Tasks

The browser rendering pipeline is interleaved with task processing.

Rendering Pipeline

  1. JavaScript → Execute event handlers, style calculations
  2. Style → Compute final styles
  3. Layout → Calculate geometry
  4. Paint → Draw pixels
  5. Composite → Layers combined

When Rendering Happens

The browser typically renders at ~60fps (every ~16.7ms). Rendering happens between macrotask processing.

// Browser checks if render is pending
// If yes, render before next macrotask
function eventLoop() {
  while (queueIsNotEmpty) {
    // Process one macrotask
    task = dequeueMacrotask();
    executeTask(task);
    
    // Process all microtasks
    drainMicrotaskQueue();
    
    // Check if render is pending
    if (renderIsPending) {
      render();
    }
  }
}

requestAnimationFrame Timing

// rAF fires before render
requestAnimationFrame(() => {
  console.log('rAF'); // Before paint
});

setTimeout(() => {
  console.log('timeout'); // After paint
}, 0);

// Output: rAF, timeout

Layout Thrashing

// BAD: causes multiple reflows
for (let i = 0; i < 100; i++) {
  element.style.width = `${i}px`; // Triggers layout
  console.log(element.offsetWidth); // Forces layout read
}

// GOOD: batch reads and writes
const width = element.offsetWidth; // Read once
for (let i = 0; i < 100; i++) {
  element.style.width = `${width + i}px`; // Write
}

Practice Problems

0/3solved
Build Macrotasks Component

Create a reusable React component implementing Macrotasks. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Macrotasks Testing

Write unit and integration tests for Macrotasks using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Macrotasks Performance

Optimize Macrotasks for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What is a macrotask?

Question 1 options

2. Why might setTimeout(fn, 0) delay more than expected?

Question 2 options

3. When does requestAnimationFrame fire?

Question 3 options

4. What is layout thrashing?

Question 4 options

Flashcards

Question

What is a macrotask?

Answer

A task from the macrotask queue (setTimeout, setInterval, DOM events) that is processed one per event loop iteration, after all microtasks.

Question

How does setTimeout(fn, 0) work?

Answer

It defers execution until the call stack is empty and all microtasks are processed. The 0ms is a minimum, not exact timing.

Question

What is the difference between setTimeout and setInterval?

Answer

setTimeout runs once after a delay. setInterval repeats at intervals, but doesn't wait for the callback to finish before scheduling the next.

Question

When does requestAnimationFrame fire?

Answer

Before the next browser paint, making it ideal for smooth animations at ~60fps.

Question

What is Macrotasks?

Answer

Macrotasks is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.Macrotasks are processed one per event loop iteration
  • 2.All microtasks run before any macrotask
  • 3.setTimeout(fn, 0) is a minimum delay, not exact
  • 4.requestAnimationFrame fires before the next paint
  • 5.Layout thrashing causes performance issues - batch reads and writes

Interview Tips

  • Explain why setTimeout(fn, 0) doesn't execute immediately
  • Compare setTimeout vs setInterval timing behavior
  • Discuss when to use requestAnimationFrame vs setTimeout
  • Explain layout thrashing and how to prevent it

Cheat Sheet

Macrotasks Cheat Sheet

Common Macrotasks

  • setTimeout() / setInterval()
  • requestAnimationFrame()
  • DOM event handlers
  • fetch() response handling

Processing Order

  1. Synchronous code
  2. ALL microtasks
  3. ONE macrotask
  4. Check if render is pending
  5. Repeat

Timing

  • setTimeout: minimum delay, not exact
  • rAF: before next paint (~60fps)
  • setInterval: doesn't wait for callback

Prevention

  • Avoid layout thrashing (batch reads/writes)
  • Use setTimeout for long tasks to yield control