Extract critical CSS

Learn how to improve render times with critical CSS technique.

Milica Mihajlija
Milica Mihajlija

The browser must download and parse CSS files before it can show the page, which makes CSS a render-blocking resource. If CSS files are big, or network conditions are poor, requests for CSS files can significantly increase the time it takes for a web page to render.

An illustration of a laptop and a mobile device with web pages overflowing the edges of screens

Inlining extracted styles in the <head> of the HTML document eliminates the need to make an additional request to fetch these styles. The remainder of the CSS can be loaded asynchronously.

HTML file with critical CSS inlined in the head
Inlined critical CSS

Improving render times can make a huge difference in perceived performance, especially under poor network conditions. On mobile networks, high latency is an issue regardless of bandwidth.

Filmstrip view comparison of loading a page with render-blocking CSS (top) and the same page with inlined critical CSS (bottom) on a 3G connection. Top filmstrip shows six blank frames before finally displaying content. Bottom filmstrip displays meaningful content in the first frame.
Comparison of loading a page with render-blocking CSS (top) and the same page with inlined critical CSS (bottom) on a 3G connection

If you have poor First Contentful Paint (FCP) and see "Eliminate render-blocking resource" opportunity in Lighthouse audits it's a good idea to give critical CSS a go.

Lighthouse audit with 'Eliminate render-blocking resource' or 'Defer unused CSS' opportunities

To minimize the number of roundtrips to first render, aim to keep above-the-fold content under 14 KB (compressed).

The performance impact you can achieve with this technique depends on the type of your website. Generally speaking, the more CSS a site has, the greater the possible impact of inlined CSS.

Overview of tools

There are a number of great tools that can automatically determine the critical CSS for a page. This is good news because doing this manually would be a tedious process. It requires analysis of the entire DOM to determine the styles that are applied to each element in the viewport.

Critical

Critical extracts, minifies and inlines above-the-fold CSS and is available as npm module. It can be used with Gulp (directly) or with Grunt (as a plugin) and there's a webpack plugin too.

It's a simple tool that takes a lot of thinking out of the process. You don't even have to specify the stylesheets, Critical automatically detects them. It also supports extracting critical CSS for multiple screen resolutions.

criticalCSS

CriticalCSS is another npm module that extracts above-the-fold CSS. It is also available as a CLI.

It doesn't have options to inline and minify critical CSS, but it does let you force-include rules that don't actually belong in critical CSS and gives you more granular control over including @font-face declarations.

Penthouse

Penthouse is a good choice if your site or app has a large number of styles or styles which are being dynamically injected into the DOM (common in Angular apps). It uses Puppeteer under the hood and even features an online hosted version too.

Penthouse doesn't detect stylesheets automatically, you have to specify the HTML and CSS files that you want to generate critical CSS for. The upside is that it's good at running many jobs in parallel.