One insertion versus a hundred
A MutationObserver reports changes to the DOM after the script finishes. The first list was changed 100 times, the second once. Both lists were laid out only once, at the next frame, because nothing read layout in between.
Every DOM change can make the browser recalculate styles, redo layout (reflow) and redraw pixels (repaint); the browser batches this work until the next frame, so the way to stay fast is to batch your changes too, build big pieces off-page with a DocumentFragment, and never alternate layout reads with writes (layout thrashing).
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Rewrite this loop so it never forces more than one layout: for (const el of items) { el.style.height = el.offsetHeight + 20 + "px"; }. Log the new heights for three 40px items.
Write renderNames(list, names) that replaces the contents of list with one <li> per name using a single insertion, and log how many <li> the list has after rendering ["Asha", "Ravi", "Meera"] twice.
Explain it without notes
What are reflow and repaint, and which kinds of change trigger each?
What is layout thrashing, and how do you fix it?
Why are ten style changes in a row usually not ten times as expensive as one?
How would you add 5,000 rows to a table efficiently?
Preview
Console
Nothing logged yet.Expected console output
Fragment is empty now: true
One by one: 100 insertion(s), 100 items
With a fragment: 1 insertion(s), 100 items