Use CSSNano and Postcss to Minify CSS in Magento 2

Hello,

Today I want to show how to use another tremendous external tool to Minify Theme's CSS files, skipping Magento 2 built-in (Core) functionality.

Minification is taking some code and using various methods to reduce its size on disk. Unlike techniques such as gzip, which preserve the original semantics of the CSS file and are therefore lossless, minification is an inherently lossy process, where values can be replaced with smaller equivalents or selectors merged, for example.

The final result of a minification step is that the resulting code will behave the same as the original file, but some parts will be altered to reduce the size as much as possible.

Combining gzip compression with minification leads to the best reduction in file size, but don't just take our word for it.

Vendor suggests trying out css-size, a module especially created to measure CSS size before & after minification.
https://npmjs.org/package/css-size

cssnano tool is one such minifier, which is written in Node.js. It's a PostCSS plugin that you can add to your build process, to ensure that the resulting stylesheet is as small as possible for a production environment.

To get started as per vendor https://cssnano.co/docs/getting-started/ page we will install cssnano and postcss CLI tools.

npm install --save-dev postcss cssnano cssnano-cli postcss-cli  

You can do it with -g for global purposes

npm install --save-dev postcss cssnano cssnano-cli postcss-cli -g  

Now that tool is installed you can type whereis command to get the path of postcss tool

whereis postcss  

Once you have done this, you will need to configure cssnano by creating a postcss.config.js file in the root of your project. This should contain cssnano as well as any other plugins that you might want for your project; as an example:

module.exports = {  
    plugins: [
        require('cssnano')({
            preset: 'default',
        }),
    ],
};

Read more about presets at https://cssnano.co/docs/presets there are tons of other options available but for Magento 2 specific I have tested with the "default" preset.

Next, we will get the THEME folder path scripted into the bash variable

THEME_FOLDER=('/workspace/magento2gitpod/pub/static/frontend/THEME/porto/en_US')  

Note: make sure you enter the correct path to your deployed theme folder in the pub/ directory

Time to push command and replace current CSS files with the minified version of them using the same file names.

find ${THEME_FOLDER[@]} \( -name '*.css' -not -name '*.min.css' -not -name '*.json' -not -name '*.js' \) -exec /usr/local/nvm/versions/node/v16.14.0/bin/postcss --replace \{} \;  

Note: You see, I've used the nvm (Node Version Manager) tool and a specific v16.14.0 version. Tool vendors claim that you can use anything after version 10 safely.

Time to measure before/after :)

npm install -g css-size  

Pick one random CSS file before running it, for example:
alt

Auspicious results :) but okay, some files give more significant differences some do not. With the Advanced preset, you can remove comments, which is good in the production environment to save more space and reduce CSS sizes.

Here you can find detailed instructions on what CSSnano Advanced preset offers:
https://cssnano.co/docs/advanced-transforms/
https://cssnano.co/docs/what-are-optimisations/

Since the tool is pure CLI you can integrate it within any deployment CI/CD process and run it always after pushing setup:static-content:deploy command from the native Magento tool.

Happy optimizing!