Prevent Layout Thrashing
What is Layout Thrashing
Layout thrashing means forcing the browser to calculate a layout that is never rendered to the screen, which hurts performance.
Why
Layout Thrashing happens, when you request layout information of an element or the document, while the layout is in an invalidated state.
// any DOM or CSSOM change flags the layout as invalid
document.body.classList.add('foo')
// reads layout == forces layout calculation
const box = element.getBoundingClientRect()
// write/mutate
document.body.appendChild(someBox)
//read/measure
const color = getComputedStyle(someOtherBox).color
Mixing Layout Read & Layout Mutation must wait for the browser to recalculate the layout and reflow to return your Layout value.
How to fix
We can resolve the problem by isolating your reads from your writes. The steps would be:
- Batch Read Layout first
- Then Mutate Layout later
// reads layout
const box = element.getBoundingClientRect()
const color = getComputedStyle(someOtherBox).color
// write
document.body.classList.add('foo')
document.body.appendChild(someBox)
Or use a library such as fastdom which abstracts those steps:
import fastdom from 'fastdom'
function resizeAllParagraphsToMatchBoxWidth(paragraphs, box) {
fastdom.measure(() => {
const width = box.offsetWidth
fastdom.mutate(() => {
for (let i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.width = width + 'px'
}
})
})
}
How to debug
Open Performance Tab
on Dev tool, slow down your CPU, and click Start Profiling
.
Find purple tasks and get info in detail:
List of commands causing Layout Thrashing we need to be careful when using it
Generally, all APIs that synchronously provide layout metrics will trigger forced reflow/layout. Check out this gist for additional cases and details.