Whether you use a UI library or handcraft your styles, shipping a significant amount of CSS delays rendering because the browser must download and parse CSS files before it can show the page.
This responsive ice cream gallery is built with Bootstrap. UI libraries like Bootstrap speed up development, but that often comes at the expense of bloated and unnecessary CSS, which can slow down your load times. Bootstrap 4 is 187 KB, while Semantic UI, another UI library, is a whopping 730 KB uncompressed. Even when minified and gzipped, Bootstrap still weighs around 20 KB, well over the 14 KB threshold for the first roundtrip.
Critical is a tool that extracts, minifies and inlines above-the-fold CSS. This allows above-the-fold content to be rendered as soon as possible, even if CSS for other parts of the page has not yet loaded. In this codelab, you'll learn how to use Critical's npm module.
Measure
- To preview the site, press View App. Then press Fullscreen .
To run a Lighthouse audit on this site:
- Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools.
- Click the Lighthouse tab.
- Click Mobile.
- Select the Performance checkbox.
- Clear the rest of the checkboxes in the Audits section.
- Click Simulated Fast 3G, 4x CPU Slowdown.
- Select the Clear Storage checkbox. With this option selected, Lighthouse will not load resources from the cache, which simulates how first-time visitors would experience the page.
- Click Run Audits.
When you run an audit on your machine, the exact results may vary, but in the filmstrip view, you'll notice the app has a blank screen for quite a while before finally rendering the content. This is why First Contentful Paint (FCP) is high and why overall performance score is not great.
Lighthouse is here to help you fix performance issues, so look for solutions in the Opportunities section. Eliminate render-blocking resources is listed as an opportunity and that's where Critical shines!
Optimize
- Click Remix to Edit to make the project editable.
To speed things up, Critical is already installed and an empty configuration file is included in the codelab.
In the configuration file critical.js
, add a reference to Critical and then invoke the critical.generate()
function. This function accepts an object containing the configuration.
const critical = require('critical');
critical.generate({
// configuration
},(err, output) => {
if (err) {
console.error(err);
} else if (output) {
console.log('Generated critical CSS');
}
});
Error handling isn't mandatory, but it's an easy way to gauge the operation success in the console.
Configure Critical
The table below contains some useful Critical options. You can check out all of the available options on GitHub.
Option | Type | Explanation |
---|---|---|
base |
string | The base directory for your files. |
src |
string | HTML source file. |
dest |
string | The target for the output file. If CSS is inlined the output file is HTML. If not, the output is a CSS file. |
width , height |
numbers | Viewport width and height in pixels. |
dimensions |
array | Contains objects with width and height properties. These objects represent the viewports you want to target with above-the-fold CSS. If you have media queries in your CSS, this allows you to generate critical CSS that covers multiple viewport sizes. |
inline |
boolean | When set to true, the generated critical CSS is inlined in the of the HTML source file. |
minify |
boolean | When set to true, Critical minifies the generated critical CSS. Can be omitted when extracting critical CSS for multiple resolutions because Critical automatically minifies it to avoid duplicate rule inclusion. |
Below is a configuration example for extracting critical CSS for multiple resolutions. Add it to critical.js
or play around and tweak the options.
critical.generate({
base: 'public/',
src: './index.html',
dest: './index.html',
inline: true,
dimensions: [
{
height: 500,
width: 300,
},
{
height: 720,
width: 1280,
},
]
}, (err, output) => {
if (err) {
console.error(err);
} else if (output) {
console.log('Generated critical CSS');
}
});
In this example, index.html
is both the source file and the destination file because the inline
option is set to true. Critical first reads the HTML source file, extracts critical CSS and then overwrites index.html
with critical CSS inlined in the <head>
.
dimensions
array has two viewport sizes specified: 300 x 500 for extra small screens and 1280 x 720 for standard laptop screens.
minify
option is omitted because Critical automatically minifies the extracted CSS when there are multiple viewport sizes specified.
Run Critical
Add Critical to your scripts in package.json
:
scripts: {
"start": "node server.js",
"critical": "node critical.js"
}
- Click Terminal (note: if the Terminal button does not show you may need to use the Fullscreen option).
To generate critical CSS, in the console, run:
npm run critical
refresh
Now in the <head>
tag of index.html
, generated critical CSS is inlined between <style>
tags, followed by a script that loads the rest of the CSS asynchronously.
Measure again
Follow the steps from the beginning of the codelab to run Lighthouse performance audit again. The results you get will look similar to this: