Performance

Critical CSS: how much the first paint moves

A 183,789-byte stylesheet in the head gives FCP 1,308 ms; inlining the first-screen rules and deferring the rest gives 276 ms, same bytes.

Key points

  • With 183,789 bytes of CSS in the head FCP is 1,308 ms; with the critical part inlined and the rest deferred it is 276 ms.
  • Total bytes do not change: only the order in which the browser uses them.
  • CLS went from 0 to 0.0001 because the deferred stylesheet lands after the first paint.
  • The home page loads 5 stylesheets for 22,486 compressed bytes: critical CSS pays off when one file is large.

Inlining critical CSS moved first paint 1,032 ms earlier: with a 183,789-byte stylesheet in the head FCP is 1,308 ms, with the first-screen rules inlined and the rest deferred it drops to 276 ms. Total bytes are the same, the order is not.

The two measurements

VariantCSS transferredFCPLCPCLS
Blocking stylesheet in the head183,789 B1,308 ms1,308 ms0
Inline critical + deferred rest183,789 B276 ms276 ms0.0001

The browser does not paint until it has downloaded and applied the blocking stylesheet: 1,032 ms of waiting on a slow link. With the critical CSS inline it paints at once and treats the rest as a file the first screen does not need.

The markup


  /* regole del primo schermo, non il framework intero */
  .hero { font: 600 28px/1.2 system-ui; }


media="print" makes the stylesheet non-blocking and onload switches it back to all as soon as it arrives. The noscript covers readers without JavaScript, who would otherwise get an unstyled page.

What inlining costs

The critical rules land in the HTML of every page: 2 KB on one page is 2 KB on a thousand pages, and they cannot be cached as a file. The rest stays a single file with a long cache, so 183,789 bytes are downloaded once. It is a trade, not a free win.

How to extract it

  • Start from the rules the first screen really needs, not from a whole reset: the home page loads 5 stylesheets, 22,486 bytes. Source: web.dev, CC BY 4.0.
  • Keep one file for the rest, with a hash in the name and a long cache. Source: web.dev, CC BY 4.0.
  • Never ship media="print" without noscript: without JavaScript the page loses its styles. Source: MDN, CC BY-SA 2.5.
  • Measure again after every change: 276 ms against 1,308 ms is this test's gap, not a constant.

The limitation to name

The test has one stylesheet and no cache: on a second visit the blocking file comes from disk or a service worker, and the gain shrinks to a few milliseconds. Inline critical CSS grows the HTML and therefore TTFB, and a missing rule makes CLS worse: here the deferred stylesheet shifted the layout by 0.0001.

Where to continue

The EneUI catalogue indexes 111,985 components, for instance pricing, and the grid of 1,556 blocks: every block adds CSS to the file. Read how to set a performance budget, what Core Web Vitals are, bundle splitting and the comparison frontend frameworks compared.

Frequently asked questions

What is critical CSS?

It is the part of the CSS needed to draw what is visible without scrolling. It goes inline in the HTML and the rest loads after the first paint.

How much does it actually save?

In our test 1,032 ms of FCP on a slow link. On a fast connection, or with the stylesheet cached, the gain falls to a few tens of milliseconds.

Is media=print with onload safe?

It works, but it needs the noscript fallback and an onload that really fires. The alternative is rel=preload followed by a rel switch, with the same risks.

Does critical CSS make CLS worse?

It can, when the critical block misses first-screen rules: the rest arrives later and moves the layout. In the test CLS went from 0 to 0.0001.

Can the build do this?

Yes. Tools that extract critical CSS read the HTML and the CSS and generate the inline block; the hard part is choosing which viewports count.