Tutorial · performance · Published 2026-08-16 · 4 min read
Request waterfalls and critical CSS
Read request waterfalls and inline critical CSS to cut LCP and render-blocking work: the waterfall view, the blocker hunt, and the pattern.
The waterfall structure
The DevTools Network panel timeline (the "waterfall" columns) is a request-duration chart: each row is a request, the length is time to completion, and the position along the horizontal axis puts related work in sequence. Three colors matter:
- The start of the row toward the left is when the request began.
- The gap between columns is waiting: TTFB waiting on the server, or a dependency not yet resolved.
- The rightmost tip is the response finished.
Reading the shape: if three requests are stacked with gaps between them, they are sequential. If they start at the same x, they ran in parallel. The biggest performance wins come from making the LCP request (the largest visible block: hero image, heading text, layout CSS) start early and reach the end early.
The blocker hunt
- Filter to the LCP element. In DevTools, find the LCP in the Performance panel trace via the Element detected as LCP marker, or inspect the largest visible block directly.
- Find its row in the waterfall. Ask: when did the request start relative to page load, and when did it finish?
- Trace back the gap. If the LCP request sits far right and everything before it is a chain of scripts, you have the classic render-blocking chain.
- Look for the "blocking" bar: the CSS/JS that precedes the LCP row and stops the renderer. The render-blocking resources article names the usual suspects.
Two details worth confirming: whether the LCP element is the font, the hero image, or the CSS (the waterfall shows which), and whether a fast site still has a slow LCP because the earliest request is a Google-Fonts stylesheet on a high-RTT network. The font loading article is the follow-up for that case.
The recipe to cut the chain
The chain pattern is usually: HTML -> CSS render-blocking -> image request -> paint. Rules that shorten it:
- Inline the critical CSS. The CSS used above the fold lives in the HTML
<head>as a<style>block, so the renderer has styles before it can parse the LCP block. Below-the-fold styles drop to a deferred stylesheet (media="print"async trick or theonloadswap). - Load the LCP image with
fetchpriority="high"and preload it. The preload hero image recipe is the sibling of this pattern, and the responsive images article decides sizes to avoid the wrong file arriving late. - Defer the below-the-fold JS and CSS. The bundle analysis in the render-blocking guide applies; here the point is the waterfall ordering, so the second-page requests move past the LCP line.
- Cull requests, not just delay them. A waterfall with 40 tiny requests still waits on all 40. The critical rendering path article covers which resources are actually required.
The inline pattern in practice
When you inline critical CSS you accept a small HTML-size increase to kill a full request round-trip before render. The maintenance rule (which every build keeps) stays: generate from the source, not by hand. The web performance audit and static CDN pages pick this up.
Concretely:
- Identify the above-the-fold selectors (the hero block, nav, the LCP image wrapper, the base font-faces needed for LCP).
- Extract those rules into a small
<style>in<head>. - Keep the full stylesheet for the rest, loaded async so
render-blockingdrops to zero.
Watch the first-paint numbers and the LCP separately: the inline block shortens the start of the chain; the deferred <link> shortens the tail. A page that "feels like it appears instantly" but keeps a long tail is normal and healthy after this change.
Measurement
- Run the same URL twice before/after with cache disabled, and compare the leftmost "Start" time of the LCP row.
- Use the Network tab > "Show overview" to see the full page timeline; the whole first column should fill fast.
- Confirm the CLS and LCP values improved using the DevTools Performance panel or the PageSpeed recipe; the waterfall reading alone cannot prove real-world field data improved, so pair them.
Prevention
Keep the rule "the LCP render needs CSS + font + hero image, nothing else before first paint". When an audit flags new render-blocking, the fix is the same loop: inline the critical, defer the rest. The dev-time habit that holds it is measuring the full waterfall on every change, which the web performance audit workflow enforces.