Why does reading DOM measurements trigger a layout/reflow?

Viewed 410

I often read that changing a style after reading the element's style is a bad practice as it triggers an unnecessary reflow. Consider this code from here:

Bad Code:

elementA.className = "a-style";
var heightA = elementA.offsetHeight;  // layout is needed
elementB.className = "b-style";       // invalidates the layout
var heightB = elementB.offsetHeight;  // layout is needed again

Good code:

elementA.className = "a-style";
elementB.className = "b-style";
var heightA = elementA.offsetHeight;   // layout is needed and calculated
var heightB = elementB.offsetHeight;   // layout is up-to-date (no work)

I am curious to know why elementA.offsetHeight will cause a layout? Here we are simply reading already applied changes, not really applying a change (like in case of elementA.className = "a-style").

1 Answers

Here we are simply reading already applied changes...

Not really. Assigning to className means the browser has to reflow, but it doesn't mean it already has reflowed when you're done assigning. It may wait (in modern browsers, will wait) until its next paint, which won't happen until after the current JavaScript code completes (at least).

But when you read a calculated property like clientHeight, the browser has to pause the JavaScript code and reflow the page so it can return an accurate number. So your "good" code does this:

elementA.className = "a-style";        // marks the layout stale
elementB.className = "b-style";        // marks the layout stale (no change)
var heightA = elementA.offsetHeight;   // triggers reflow
var heightB = elementB.offsetHeight;   // no need for reflow, the layout isn't stale
Related