intermediate

Layout thrashing

Avoid forced synchronous layout by batching DOM reads and writes and measuring layout at predictable points.

Layout thrashing (forced synchronous layout) happens when JavaScript alternates DOM writes with layout reads. Each read may force the browser to flush pending style and layout work immediately.

					// Bad: read-write interleaving
elements.forEach((el) => {
  el.style.width = el.offsetWidth + 10 + 'px'; // read then write per iteration
});

// Better: batch reads, then writes
const widths = elements.map((el) => el.offsetWidth);
elements.forEach((el, i) => {
  el.style.width = widths[i] + 10 + 'px';
});
				

APIs like `offsetWidth`, `getBoundingClientRect`, and `scrollTop` trigger layout when dirty. Batch reads, then writes; use `requestAnimationFrame` for visual updates; throttle scroll and resize handlers.

On interviews: link specific DOM APIs to forced synchronous layout and how batching fixes frame drops.

The trade-off is imperative DOM measurement versus declarative CSS layout when either could solve the problem.

Common pitfalls: optimizing selectors while ignoring read-write loops; measuring layout inside hot scroll handlers.

Checklist:

  • Read all measurements first, then mutate.
  • Use rAF for visual DOM updates.
  • Throttle expensive resize/scroll work.
  • Prefer CSS layout over JS measurement loops.