Efficient DOM Manipulation: Patterns and Anti-Patterns
The DOM is often the slowest part of a web application. Here is how I minimize layout thrashing and keep user interactions responsive. The DOM is not slow because of individual operations. Setting a single property or reading a value takes microseconds. It is slow because of layout thrashing. alternating reads and writes that force the browser to repeatedly recalculate the positions of elements. A loop that reads an elements offsetHeight, then sets a style property, then reads another offset value, then sets another style can trigger dozens of forced layouts in rapid succession. Understanding Layout Thrashing Layout thrashing happens when you alternate between reading layout properties and writing style properties. The browser batches style writes for efficiency, but a layout read forces it to flush the pending writes and recalculate the layout immediately. If you then write another style and read again, you force another recalculation. // BAD: Layout thrashing elements.forEach(el => { const width = el.offsetWidth; // Read (forces layout) el.style.width = width + 10 + 'px'; // Write (invalidates layout) const height = el.offsetHeight; // Read (forces layout AGAIN) el.style.height = height + 5 + 'px'; // Write (invalidates again)…