4 ms·
All browsers have used a dirty bit for layout for at least the past 2 decades (source: I have worked on browser engines for 2 decades). This is not some new Chr
by om2 6y ago
All browsers have used a dirty bit for layout for at least the past 2 decades (source: I have worked on browser engines for 2 decades). This is not some new Chrome thing. And all browsers continue to have that same hazard that querying layout-dependent properties forces a synchronous style recalc and layout.
The benefit of React (if any; it has a lot more overhead than vanilla JS+DOM) is that you can't hit that specific pitfall of forcing layout interspersed with DOM or style manipulation.
- twsted 6y ago> And all browsers continue to have that same hazard that querying layout-dependent properties forces a synchronous style recalc and layout. Could you explain why? Is the following true even when the parent is already in the DOM? parent.appendChild(document.createElement('div')); // Fast; ~50 us let w = parent.innerWidth; // Slow, forces reflow; ~20 ms
- om2 6y agoThis is a slightly weird example because it's adding an empty <div>, so you can imagine it could be optimized if it provably has no effect on layout. But let's imagine instead that the node added to parent was a div with a text child. Or, slightly less obviously, the div is getting added in a document with a style rule of `div { width: 1000px;} In that case, the width could change. So the browser engine's options are: 1. Return a stale value from parent.innerWidth for now, and just lazily update style at the next event loop iteration. 2. Synchronously update style and layout (note, this update is not as expensive as a from-scratch layout), and return the up-to-date value of parent.innerWidth It turns out that, historically, the earliest browsers with scripting did option (2), and websites came to depend on it. So browsers had to keep on doing it, and so forth. Many folks in the web standards world would like to find away out of this dilemma, where DOM mutation doesn't risk this kind of performance hazard. You could also imagine an extra bad option: 3. Every time the DOM (or the CSSOM) is mutated, synchronously update layout. This is super expensive in the face of repeated DOM mutations. Repeated DOM mutations (e.g. adding multiple elements, setting multiple attributes) are way more common than repeatedly getting style/layout-dependent attributes. (3) has the same observable functional behavior as (2), but it's a lot slower, because it will do a lot of unnecessary layouts. I'm not totally sure if this explains everything you were wondering about, but I hope it helps some.
- twsted 6y agoYes, thank you. So browsers normally optimize the first call, but are forced to update at the second one. As a related note, are you considering the content-visibility property for webkit?
- om2 6y agoWe are aware of the interest and I think we're generally in favor of it, but nothing specific to announce about timing.
- SirHound 6y ago> is that you can't hit that specific pitfall of forcing layout interspersed with DOM or style manipulation. This isn't true though, useLayoutEffects that perform a read/write littered through your code is going to quite easily induce layout thrashing and there's no way of splitting this throughout a tree
- om2 6y agoOK, this is the part where I have to admit I know a lot less about React than about browser engines. :-)