Render-blocking resources determine the first visible moment
Aliases: render-blocking CSS · first paint gate · CSSOM block · blocking fonts
What it is
Until critical CSS, synchronous scripts, and fonts still in their blocking period are ready, the browser may refuse to paint a first frame. Those assets are render-blocking resources. They gate the first visible moment: when the screen stops being blank, not when controls become tappable or the main thread goes idle. Visible and interactive are different clocks; this leaf is only the first—who holds the first frame.
Why it happens
An external stylesheet makes the parser wait on CSSOM; without it, engines prefer not to flash unstyled content, so first paint waits. A synchronous script pauses parsing, so later HTML never enters the DOM until the script finishes, and first paint is delayed again. A font in a blocking strategy can occupy layout without painting glyphs, so the first screen looks like missing text. The chain is: blocking resource → deferred first frame → the user still faces blank or incomplete first paint.
This is a different timeline from late content shoving already-painted nodes. Blocking happens before frame one; there are no laid-out nodes to push yet. Layout shift happens after frame one. Delaying first paint can even reduce shift, because more boxes are complete when pixels first appear—at the cost of a longer blank. Speeding first paint means shortening the blocking chain, not converting blockers into post-paint inserts.
Where it stops holding
Stylesheets whose media does not match, async/deferred scripts, and non-blocking font strategies do not hold first paint by default. HTTP/2 multiplexing shortens transfer; it does not change “no first paint until CSSOM.” Server-rendered HTML that still links a huge blocking stylesheet still waits on that sheet. Native view trees do not use this CSSOM gate; their first frame is bound by launch and main-thread setup instead. Cached blockers can make first paint look early in the lab; a cold field load will not.
Applying it
- Inline or split CSS that the first screen actually uses; load the rest asynchronously. Get synchronous scripts off the first-paint critical path.
- Preload fonts to shrink the blocking window; do not hold the whole first paint until a full font package lands.
- On the waterfall, mark CSS, sync JS, and blocking fonts that are still open at frame one, and make each non-blocking or smaller.
- Verify under a throttled network: time the first contentful paint, then remove or defer suspects. First paint should move earlier, without turning the old blocking work into inserts into an already-painted flow.
Related
- Same group: R3.05.1 Late-arriving content pushes already laid-out nodes · R3.05.2 Displacement causes misclicks · R3.05.3 Dynamic content needs reserved space · R3.05.5 Already-interactive regions must not be reflowed by late content · R3.05.6 Async inserts should occupy positions that do not interrupt reading
- Adjacent: R3.15 First-paint metrics and interaction readiness · R3.06 Font Loading · I2.07 Perceived performance
- Search terms:
render-blocking·first paint·CSSOM
Cards in the same group
- R3.05.1Late-arriving content pushes already laid-out nodes
- R3.05.2A control that moves after render steals the tap meant for it
- R3.05.3Dynamic content needs reserved space
- R3.05.5Already-interactive regions must not be reflowed by late content
- R3.05.6Async inserts should occupy positions that do not interrupt reading