Layout Thrashing Starts When DOM Reads and Writes Fight Each Other_
Geometry APIs like `getBoundingClientRect()` are useful, but they become expensive when code repeatedly forces fresh layout in the middle of style and DOM updates.
The browser wants to batch style calculation and layout work. Performance problems show up when application code keeps interrupting that plan by alternating DOM writes and layout reads in tight loops.
That pattern is usually called layout thrashing.
The Bug Pattern
This is the expensive shape:
for (const item of items) { item.style.width = "200px"; const rect = item.getBoundingClientRect(); item.style.height = `${rect.width}px`;}
Every call to getBoundingClientRect() may force the browser to flush pending layout work before it can answer. If this runs during scroll, resize, or animation, the UI gets janky fast.
That is not the only possible fix, but it shows the underlying rule: avoid forcing the browser to repeatedly recompute layout inside frame-sensitive code.
When This Actually Matters
You usually feel it in:
scroll handlers
animation loops
drag-and-drop interactions
large lists with direct DOM manipulation
The browser is fast when you let it batch work. It becomes expensive when you make it answer geometry questions immediately after every write.
If the code has to run during animation or interaction, requestAnimationFrame is often the right place to schedule batched DOM work so reads and writes happen in a more predictable frame boundary.