How it works
The explanation, with examples you can run.
The first render
The HTML parser builds the DOM incrementally, as bytes arrive. When it meets a stylesheet, it keeps parsing, but the browser won't render until that CSS has been fetched and parsed: the cascade means any later rule could restyle anything, so painting early would only flash wrong content. When the parser meets a classic <script> without async or defer, it stops, because the script might call document.write or read the DOM built so far. The script also waits for any stylesheet before it, since it might read computed styles.
That gives the usual rules for a fast first paint:
- Keep the CSS needed for the first screen small, and load it early.
- Mark scripts
defer(run in order after parsing) orasync(run as soon as they arrive, in any order), or usetype="module", which defers by default. - Let the preload scanner help: it looks ahead in the raw HTML for images, scripts and stylesheets and starts fetching them early. Resources that only JavaScript discovers miss out on that.
Every frame after that
Between tasks, the event loop may run a rendering step: requestAnimationFrame callbacks, then style recalculation, layout, paint and composite. Each step only reruns if something it depends on changed:
| You change | Reruns |
|---|---|
width, margin, font-size, adding nodes | style, layout, paint, composite |
color, background, box-shadow | style, paint, composite |
transform, opacity (on its own layer) | style, composite |
Compositing can happen on a separate thread, which is why a CSS transform animation can stay smooth while JavaScript is busy, and a left animation can't.
Forced layout
Style changes are normally batched until the next frame. Reading geometry (offsetWidth, getBoundingClientRect(), scrollTop) right after a change forces the browser to do layout immediately so it can answer. Done once, that is fine; done in a loop that alternates reads and writes, it is layout thrashing. Batch the reads, then the writes, or move the writes into requestAnimationFrame.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.