Changing the DOM is much slower than normal JavaScript, because the browser may have to recalculate sizes and positions (layout or reflow) and redraw (paint). A few habits keep pages fast. They matter most for long lists and frequent updates.
1. Do less DOM work
// Slower: touches the page 1000 times
for (let i = 0; i < 1000; i++) {
list.innerHTML += `<li>${i}</li>`;
}
Each innerHTML += throws away and rebuilds all existing children.
2. Batch: build first, insert once
<ul id="list"></ul>
<script>
const list = document.querySelector("#list");
const fragment = document.createDocumentFragment();
for (let i = 1; i <= 1000; i++) {
const li = document.createElement("li");
li.textContent = "Item " + i;
fragment.append(li);
}
list.append(fragment); // one insertion
console.log(list.children.length); // → 1000
</script>
A DocumentFragment is a light container that is not part of the page. Inserting it moves all its children in one go. Building one HTML string and assigning it once also works.
3. Avoid reading and writing layout in a loop
Reading things like offsetHeight forces the browser to calculate layout. Mixing reads and writes causes it to do so again and again (“layout thrashing”).
// Bad: read, write, read, write...
for (const box of boxes) {
box.style.width = box.parentElement.offsetWidth + "px";
}
// Better: read everything first, then write
const widths = boxes.map(box => box.parentElement.offsetWidth);
boxes.forEach((box, i) => { box.style.width = widths[i] + "px"; });
4. Change classes, not many styles
One classList.toggle() is cheaper and clearer than setting five style properties.
5. Use event delegation
One listener on a list can handle thousands of items, instead of one listener per item. See Event Delegation.
6. Use CSS for animation
Moving things with CSS transform and transition is smoother than moving them with JavaScript timers. Prefer requestAnimationFrame when you must animate in code.
7. Large lists
For very long lists (thousands of rows), render only what is visible (“virtual scrolling”), or paginate. See Performance for more.
8. Measure first
Do not optimise by guesswork. Use the browser’s Performance panel to see where time goes, and fix the real bottleneck. For a few dozen elements, simple code is perfectly fast.