Минификация CSS — процесс удаления из CSS-файлов всего лишнего: пробелов, переносов строк, комментариев, дублирующихся конструкций и других элементов, не влияющих на работу стилей. После минификации итоговый CSS становится значительно меньше, что уменьшает размер сборки и ускоряет загрузку сайта.
В экосистеме Webpack за минификацию CSS отвечает плагин Webpack
CssMinimizerWebpackPlugin. Он появился как современная
замена устаревшим решениям вроде
optimize-css-assets-webpack-plugin.
Основные задачи плагина:
Плагин работает поверх библиотеки cssnano, которая
выполняет реальную оптимизацию CSS.
Для работы необходимо установить сам плагин и webpack:
npm install --save-dev css-minimizer-webpack-plugin
Обычно плагин используется вместе с:
mini-css-extract-plugincss-loaderstyle-loaderПростейшая конфигурация:
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
mode: 'production',
optimization: {
minimizer: [
`...`,
new CssMinimizerPlugin(),
],
},
};
...Конструкция:
minimizer: [
`...`,
new CssMinimizerPlugin(),
]
имеет важное значение.
Webpack по умолчанию в production-режиме уже использует JavaScript-минимизатор:
TerserWebpackPlugin
Если полностью переопределить массив minimizer,
стандартный JS-минимизатор исчезнет.
Неправильно:
optimization: {
minimizer: [
new CssMinimizerPlugin(),
],
}
В этом случае CSS будет минифицироваться, а JavaScript — нет.
Правильно:
optimization: {
minimizer: [
`...`,
new CssMinimizerPlugin(),
],
}
... сохраняет стандартные minimizer-плагины Webpack.
Исходный CSS:
body {
margin: 0;
padding: 0;
}
.container {
color: red;
color: red;
}
После минификации:
body{margin:0;padding:0}.container{color:red}
Удаляются:
Часто CssMinimizerWebpackPlugin используется вместе с
извлечением CSS в отдельные файлы.
npm install --save-dev \
mini-css-extract-plugin \
css-loader \
css-minimizer-webpack-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
mode: 'production',
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/main.[contenthash].css',
}),
],
optimization: {
minimizer: [
`...`,
new CssMinimizerPlugin(),
],
},
};
Извлекает CSS из JavaScript-бандла в отдельный файл.
Без него CSS может внедряться прямо в <style>
через JavaScript.
Позволяет импортировать CSS:
import './styles.css';
Минифицирует итоговый CSS после сборки.
Минификация обычно нужна только в production-сборке.
Часто используется условная конфигурация:
const isProd = process.env.NODE_ENV === 'production';
Пример:
optimization: {
minimizer: isProd
? [
`...`,
new CssMinimizerPlugin(),
]
: [],
},
Минифицированный CSS сложно читать. Для отладки используются source maps.
Конфигурация:
module.exports = {
devtool: 'source-map',
optimization: {
minimizer: [
`...`,
new CssMinimizerPlugin(),
],
},
};
Плагин поддерживает не все source map режимы.
Рекомендуемые варианты:
devtool: 'source-map'
или:
devtool: 'inline-source-map'
Плагин позволяет передавать параметры в cssnano.
Пример:
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
'default',
{
discardComments: {
removeAll: true,
},
},
],
},
})
Исходный CSS:
/* Main styles */
body {
margin: 0;
}
После сборки:
body{margin:0}
Комментарии полностью удаляются.
cssnano использует presets — наборы оптимизаций.
Наиболее популярный:
preset: 'default'
Пример:
new CssMinimizerPlugin({
minimizerOptions: {
preset: 'default',
},
})
Некоторые CSS-оптимизации могут быть нежелательными.
Например:
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
'default',
{
mergeLonghand: false,
},
],
},
})
Опция объединяет CSS-свойства.
Исходный CSS:
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 20px;
После оптимизации:
padding:10px 20px
Иногда подобное преобразование может ломать логику CSS.
Минификация CSS может быть тяжёлой операцией для больших проектов.
Плагин поддерживает параллельную обработку:
new CssMinimizerPlugin({
parallel: true,
})
Webpack создаёт несколько worker-процессов.
Каждый worker:
Это ускоряет production-сборку.
Можно указать число worker-процессов:
new CssMinimizerPlugin({
parallel: 4,
})
Можно ограничивать набор файлов для минификации.
Пример:
new CssMinimizerPlugin({
exclude: /vendor/,
})
new CssMinimizerPlugin({
include: /\.min\.css$/,
})
Определяет, какие файлы должны минифицироваться.
new CssMinimizerPlugin({
test: /\.css$/i,
})
Плагин работает не только с обычным CSS.
Пример цепочки:
npm install --save-dev \
sass \
sass-loader \
css-loader \
mini-css-extract-plugin \
css-minimizer-webpack-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
mode: 'production',
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin(),
],
optimization: {
minimizer: [
`...`,
new CssMinimizerPlugin(),
],
},
};
SCSS проходит несколько этапов:
SCSS
↓
sass-loader
↓
css-loader
↓
MiniCssExtractPlugin
↓
CssMinimizerPlugin
↓
Готовый CSS
Часто CSS проходит через PostCSS перед минификацией.
Пример:
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
]
После PostCSS CSS попадает в CssMinimizerPlugin.
Преобразует CSS:
Отвечает только за оптимизацию и сжатие.
Плагин способен:
Исходный код:
@media screen and (max-width: 768px) {
.box {
margin: 0px;
}
}
После минификации:
@media screen and (max-width:768px){.box{margin:0}}
Исходный CSS:
color: #ffffff;
После минификации:
color:#fff
Исходный CSS:
margin: 0px;
padding: 0em;
После:
margin:0;padding:0
Исходный CSS:
.button {
color: red;
color: red;
}
После:
.button{color:red}
Плагин корректно работает с CSS Custom Properties.
Исходный CSS:
:root {
--main-color: red;
}
После минификации:
:root{--main-color:red}
Плагин совместим с CSS Modules.
Пример:
{
test: /\.module\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
},
},
],
}
Минификация применяется уже после генерации локальных классов.
Минификация CSS:
На крупных проектах экономия может составлять сотни килобайт.
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
mode: 'production',
devtool: 'source-map',
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash].css',
}),
],
optimization: {
minimize: true,
minimizer: [
`...`,
new CssMinimizerPlugin({
parallel: true,
minimizerOptions: {
preset: [
'default',
{
discardComments: {
removeAll: true,
},
},
],
},
}),
],
},
};
...minimizer: [
new CssMinimizerPlugin(),
]
Ломает JS-минимизацию.
use: [
'style-loader',
'css-loader',
]
CSS внедряется через JavaScript вместо отдельного файла.
mode: 'development'
Минификация может работать некорректно или отсутствовать.
Неправильно:
use: [
'css-loader',
MiniCssExtractPlugin.loader,
]
Правильно:
use: [
MiniCssExtractPlugin.loader,
'css-loader',
]
Минификация CSS критически важна при:
Минифицированные CSS-файлы часто используют:
filename: '[name].[contenthash].css'
Это позволяет:
Пример:
| Состояние | Размер |
|---|---|
| Исходный CSS | 420 KB |
| После минификации | 280 KB |
| После gzip | 45 KB |
Минификация и gzip — разные процессы.
Удаляет лишние символы.
Архивирует данные при передаче по сети.
Обычно используются вместе.
CssMinimizerWebpackPlugin: