CSS files can contain unnecessary characters, such as comments, whitespaces, and indentation. In production, these characters can be safely removed, to reduce file size without affecting how the browser processes the styles. This technique is called minification.
Loading unminified CSS
Take a look at the following CSS block:
body {
font-family: "Benton Sans", "Helvetica Neue", helvetica, arial, sans-serif;
margin: 2em;
}
/* all titles need to have the same font, color and background */
h1 {
font-style: italic;
color: #373fff;
background-color: #000000;
}
h2 {
font-style: italic;
color: #373fff;
background-color: #000000;
}
This content is easy to read, at the cost of producing a larger than necessary file:
- It uses spaces for indentation purposes and contains comments, which are ignored by the browser, so they can be removed.
- The
<h1>
and<h2>
elements have the same styles: instead of declaring them separately: "h1 {...} h2 {...}
" they could be expressed as "h1, h2{...}
". - The background-color,
#000000
could be expressed as just#000
.
After making these changes, you would obtain a more compact version of the same styles:
body{font-family:"Benton Sans","Helvetica Neue",helvetica,arial,sans-serif;margin:2em}h1,h2{font-style:italic;color:#373fff;background-color:#000}
You probably don't want to write CSS like that. Instead, you can write CSS as usual, and add a minification step to your build process. In this guide, you'll learn how to do it by using a popular build tool: webpack.
Measure
You'll apply CSS minification to a site that has been used in other guides: Fav Kitties. This version of the site uses a cool CSS library: animate.css, to animate different page elements when a user votes for a cat 😺.
As a first step, you need to understand what would be the opportunity after minifying this file:
- Open the measure page.
- Enter the URL:
https://fav-kitties-animated.glitch.me
and click Run Audit. - Click View report.
- Click on Performance and go the Opportunities section.
The resulting report shows that up to 16 KB can be saved from the animate.css file:
Now inspect the content of the CSS:
- Open the Fav Kitties site in Chrome. (It might take a while for Glitch servers to respond the first time.)
- Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools.
- Click the Network tab.
- Click the CSS filter.
- Select the Disable cache checkbox.
- Reload the app.
The page is requesting two CSS files, of 1.9KB and 76.2KB respectively.
- Click animate.css.
- Click the Response tab, to see the file contents.
Note that the stylesheet contains characters for whitespaces and indentation:
Next, you'll add some webpack plugins to your build process to minify these files.
CSS Minification with webpack
Before jumping into the optimizations, take some time understanding how build process for the Fav Kitties site works:
By default, the resulting JS bundle that webpack produces would contain the content of the CSS files inlined. Since we want to maintain separate CSS files, we are using two complementary plugins:
- mini-css-extract-plugin will extract each style sheet into its own file, as one of the steps of the build process.
- webpack-fix-style-only-entries is used to correct an issue in wepback 4, to avoid generating an extra JS file for each CSS file listed in webpack-config.js.
You will now make some changes in the project:
- Open the Fav Kitties project in Glitch.
- To view the source, press View Source.
- Click Remix to Edit to make the project editable.
- Click Terminal (note: if the Terminal button does not show you may need to use the Fullscreen option).
To minify the resulting CSS, you'll use the optimize-css-assets-webpack-plugin:
- In Glitch console, run
npm install --save-dev optimize-css-assets-webpack-plugin
. - Run
refresh
, so the changes are synchronized with the Glitch editor.
Next, go back to the Glitch editor, open the webpack.config.js file, and make the following modifications:
Load the module at the beginning of the file:
js
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
Then, pass an instance of the plugin to the plugins array:
js
plugins: [
new HtmlWebpackPlugin({template: "./src/index.html"}),
new MiniCssExtractPlugin({filename: "[name].css"}),
new FixStyleOnlyEntriesPlugin(),
new OptimizeCSSAssetsPlugin({})
]
After making the changes a rebuild of the project will be triggered.
This is how the resulting webpack.config.js will look like:
Next, you'll check the result of this optimization with performance tools.
Verify
- To preview the site, press View App. Then press Fullscreen .
If you got lost in any previous step, you can click here, to open an optimized version of the site.
To inspect the size and content of the files:
- Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools.
- Click the Network tab.
- Click the CSS filter.
- Select the Disable cache checkbox if it isn't already.
- Reload the app.
You can inspect these files, and see that the new versions don't contain any whitespaces. Both files are much smaller, in particular, the animate.css has been reduced in ~26%, saving ~20KB!
As a final step:
- Open the measure page.
- Enter the URL of the optimized site.
- Click View report.
- Click on Performance and find the Opportunities section.
The report doesn't show "Minify CSS" as "Opportunity" anymore, and has now moved to "Passed Audits" section:
Since CSS files are render-blocking resources, if you apply minification on sites that use large CSS files, you can see improvements on metrics like First Contentful Paint.
Next steps and resources
In this guide, we've covered CSS Minification with webpack, but the same approach can be followed with other build tools, like gulp-clean-css for Gulp, or grunt-contrib-cssmin for Grunt.
Minification can also be applied to other types of files. Check out the Minify and compress network payloads guide to learn more about tools to minify JS, and some complementary techniques, like compression.