Урок 03

Оптимизация CSS: Autoprefixer, PostCSS, критический CSS

Зачем оптимизировать CSS

Проблемы:

  • Размер — 500 KB CSS легко.
  • Парсинг — блокирует рендер.
  • Совместимость — префиксы для старых браузеров.
  • Неиспользуемое — 90% утилит не применяются.

Что даёт:

  • Быстрее загрузка.
  • Меньше трафика.
  • Лучше Core Web Vitals.
  • Совместимость.

PostCSS

Что такое: инструмент для трансформации CSS через JS-плагины.

Не препроцессор. Не заменяет SCSS. Работает после него.

Что делает:

  • Autoprefixer — префиксы.
  • CSS Nano — минификация.
  • postcss-preset-env — современный синтаксис для старых браузеров.
  • postcss-import — инлайн импортов.
  • cssnano — оптимизация.

Правило: SCSS → PostCSS → CSS.

Установка

npm install -D postcss postcss-cli autoprefixer cssnano

postcss.config.js

export default {
    plugins: {
        autoprefixer: {},
        cssnano: process.env.NODE_ENV === 'production' ? {} : false,
    },
};

Что даёт: при сборке применяются плагины.

Autoprefixer

Что делает: добавляет -webkit-, -moz- и т.д.

До:

.box {
    display: flex;
    user-select: none;
    appearance: none;
}

После:

.box {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

Что даёт: работает в старых Safari, Edge.

Browserslist

Указать, какие браузеры поддерживать:

package.json:

{
    "browserslist": [
        "last 2 versions",
        "not dead",
        "> 1%",
        "not ie 11"
    ]
}

Или .browserslistrc:

last 2 versions
not dead
> 1%
not ie 11

Что означает:

  • last 2 versions — последние 2 версии.
  • not dead — активно поддерживаемые.
  • > 1% — доля рынка.
  • not ie 11 — исключить IE 11.

Правило: чем меньше список — тем меньше CSS.

CSS Nano

Минификация:

До:

.button {
    background: #ffffff;
    padding: 12px 24px;
    border: none;
}

.card {
    background: #ffffff;
    padding: 12px 24px;
}

После:

.button{background:#fff;padding:12px 24px;border:none}.card{background:#fff;padding:12px 24px}

Что делает:

  • Убирает пробелы.
  • Сокращает цвета.
  • Убирает последнюю ;.
  • Мержит медиазапросы.

Экономия: 20-40%.

PurgeCSS

Удаление неиспользуемого CSS:

npm install -D @fullhuman/postcss-purgecss

postcss.config.js:

import purgecss from '@fullhuman/postcss-purgecss';

export default {
    plugins: [
        purgecss({
            content: ['./src/**/*.html', './src/**/*.js', './src/**/*.php'],
            safelist: ['active', 'disabled', /^modal-/],
        }),
    ],
};

Что даёт: CSS уменьшается на 50-90%.

⚠️ Может удалить динамические классы. safelist решает.

Critical CSS

Проблема: CSS блокирует рендер.

Решение: критический CSS — в <head> инлайн, остальное — асинхронно.

Что такое критический:

  • Стили выше первого экрана.
  • Header, hero, навигация.
  • Основная типографика.

Что инлайн:

<head>
    <style>
        /* Критический CSS */
        body { margin: 0; font-family: system-ui; }
        .header { display: flex; padding: 16px; }
    </style>

    <link
        rel="preload"
        href="style.css"
        as="style"
        onload="this.onload=null;this.rel='stylesheet'"
    >
    <noscript>
        <link rel="stylesheet" href="style.css">
    </noscript>
</head>

Что даёт: страница отрисовывается сразу.

Инструменты Critical CSS

critical (npm):

npm install -D critical
import { generate } from 'critical';

await generate({
    inline: true,
    base: 'dist/',
    src: 'index.html',
    target: 'index.html',
    width: 1300,
    height: 900,
});

Что даёт: автоматически вырезает критический CSS.

Vite + PostCSS

Установка:

npm install -D postcss autoprefixer cssnano

postcss.config.js:

export default {
    plugins: {
        autoprefixer: {},
        cssnano: process.env.NODE_ENV === 'production' ? {} : false,
    },
};

Vite подхватит автоматически.

Next.js + PostCSS

Установка:

npm install -D postcss autoprefixer

postcss.config.js:

module.exports = {
    plugins: {
        autoprefixer: {},
    },
};

Next.js настроен из коробки.

Laravel Mix + PostCSS

webpack.mix.js:

const mix = require('laravel-mix');

mix.sass('resources/scss/app.scss', 'public/css')
    .options({
        postCss: [
            require('autoprefixer'),
        ],
    });

Практика: анализ CSS

Что смотреть:

  • Размер — dist/style.css.
  • Coverage — DevTools → Coverage.
  • Неиспользуемые — PurgeCSS.

DevTools → Coverage:

Ctrl+Shift+P → Show Coverage

Что показывает:

  • Какой CSS использован.
  • Какой не использован.
  • Процент.

Правило: 40-60% CSS обычно не используется на первой странице.

Практический стек

Разработка:

SCSS → PostCSS (autoprefixer) → CSS

Продакшен:

SCSS → PostCSS (autoprefixer + cssnano + purgecss) → CSS → Critical inline

Что даёт:

  • В dev — читаемость.
  • В prod — минимальный размер.
  • Совместимость.

Пример полной настройки

package.json:

{
    "scripts": {
        "build:css": "sass src/scss/main.scss src/css/main.css --style=expanded",
        "build:css:prod": "sass src/scss/main.scss dist/main.css --style=compressed --no-source-map && postcss dist/main.css -o dist/main.css",
        "watch:css": "sass --watch src/scss/main.scss:src/css/main.css"
    },
    "browserslist": [
        "last 2 versions",
        "> 1%",
        "not dead"
    ]
}

postcss.config.js:

import purgecss from '@fullhuman/postcss-purgecss';
import cssnano from 'cssnano';
import autoprefixer from 'autoprefixer';

export default {
    plugins: [
        autoprefixer,
        ...(process.env.NODE_ENV === 'production'
            ? [
                  purgecss({
                      content: ['./src/**/*.html', './src/**/*.php'],
                      safelist: [/^modal/, /^tooltip/],
                  }),
                  cssnano({ preset: 'default' }),
              ]
            : []),
    ],
};

Практика

1. Установите PostCSS + autoprefixer.

2. Настройте browserslist.

3. Скомпилируйте SCSS → CSS → PostCSS.

4. Проверьте префиксы в выходном CSS.

5. Включите cssnano — сравните размер.

6. Включите PurgeCSS — насколько меньше?

7. Добавьте критический CSS в <head>.

8. Замерьте Lighthouse → Performance.

Частые ошибки

1. PostCSS вместо SCSS:

Думают, что заменяет

Решение: PostCSS — после SCSS.

2. Autoprefixer без browserslist:

Огромный CSS

Решение: указать список.

3. PurgeCSS удалил динамические классы:

Кнопка сломалась

Решение: safelist.

4. Критический CSS в dev:

Запутанный workflow

Решение: только в prod-сборке.

5. Без preload:

CSS не загружается асинхронно

Решение: rel="preload" + onload.

6. <noscript> забыт:

Без JS — без стилей

Решение: добавить <noscript>.

7. Минификация в dev:

Тяжело отлаживать

Решение: только в prod.

8. Нет source maps в prod?:

Ок не иметь. Но в dev — обязательно.

Итог

  • PostCSS — после SCSS.
  • Autoprefixer — префиксы.
  • Browserslist — какие браузеры.
  • CSS Nano — минификация.
  • PurgeCSS — удаление неиспользуемого.
  • Critical CSS — инлайн в head.
  • Preload — асинхронная загрузка.
  • Vite / Next / Laravel Mix — встроенно.
  • DevTools Coverage — анализ использования.
  • Правило: SCSS → PostCSS → CSS.

Дальше — ARIA и доступность в интерфейсах.