CodeOath
← All posts
JavaScript75 min total · 15 parts

JavaScript Core Concepts: Scope, Closures, `this`, and the Event Loop

Contents — Part 13 of 15: Where Rendering Fits In
Part 13 of 15 · ~1 min

Where Rendering Fits In

In a browser, the event loop doesn't just alternate between microtasks and macrotasks — it also has to paint the page. The browser typically drains the microtask queue, then has an opportunity to render an updated frame, and only then moves on to the next macrotask, which is why microtask work is generally considered "before the next paint" while macrotask work happens "after."

requestAnimationFrame(callback) schedules a callback to run immediately before the browser's next repaint — the correct tool for any visual update synchronized to the display's refresh rate (an animation, a scroll-linked effect), rather than setTimeout, which has no relationship to the paint cycle at all:

function animate() {
  element.style.transform = `translateX(${position}px)`;
  position += 2;
  if (position < 300) requestAnimationFrame(animate); // schedules the NEXT frame's update
}
requestAnimationFrame(animate);

Using setTimeout for animation instead can produce visibly janky motion, since its timing has no coordination with the browser's actual repaint schedule — requestAnimationFrame is timed to the display, typically around 60 times per second on a standard 60Hz screen, and automatically pauses in a backgrounded tab, which also makes it more battery-friendly than a setInterval loop that keeps firing regardless of visibility.