Script Valley
JavaScript: The Complete Language
DOM Manipulation and Browser APIsLesson 5.5

Timers, requestAnimationFrame, and browser rendering performance

setTimeout, setInterval, clearTimeout clearInterval, requestAnimationFrame, requestIdleCallback, animation loop pattern, layout thrashing, will-change, performance.now

Scheduling Work at the Right Time

JavaScript provides several scheduling APIs. Choosing the right one for animations, timers, and deferred work prevents janky interfaces and wasted CPU cycles. The browser renders at roughly 60 frames per second — every 16ms. Your code must work within that budget.

setTimeout and setInterval

const id = setTimeout(() => console.log("After 1s"), 1000);
clearTimeout(id); // cancel before it fires

const tick = setInterval(() => updateClock(), 1000);
clearInterval(tick); // always clean up when done

requestAnimationFrame — Smooth Animations

Runs your callback just before the browser paints the next frame. Automatically syncs to the display refresh rate and pauses when the tab is hidden — saving battery and CPU.

function animate(timestamp) {
  const elapsed = timestamp - startTime;
  element.style.transform = `translateX(${elapsed * 0.1}px)`;

  if (elapsed < 1000) {
    requestAnimationFrame(animate); // schedule next frame
  }
}
const startTime = performance.now();
requestAnimationFrame(animate);

Avoiding Layout Thrashing

// BAD — interleaved reads/writes force reflow each iteration
boxes.forEach(box => {
  const h = box.offsetHeight; // read — triggers layout
  box.style.height = h * 2 + "px"; // write
});

// GOOD — batch all reads, then all writes
const heights = boxes.map(b => b.offsetHeight);
boxes.forEach((box, i) => box.style.height = heights[i] * 2 + "px");