
⚡ Критический CSS: что это, как сгенерировать и ускорить загрузку сайта
Сайт грузится 3 секунды, и посетитель уходит. Вы открываете Google PageSpeed Insights, а там красный диагноз: «Устраните CSS, блокирующий рендеринг». Знакомо? По данным HTTP Archive за 2025 год, медианная страница тащит 7 внешних таблиц стилей, а средний вес CSS перевалил за 120 КБ. Каждый файл в <head>, шлагбаум между пользователем и контентом.
Дело не в «тяжёлом» CSS. Браузер не покажет ни пикселя, пока не скачает и не разберёт ВСЕ стили. Даже те, что отвечают за футер на 4000-м пикселе. Решение, Critical CSS: техника, которая вырезает из полного набора стилей только то, что нужно для видимой области экрана, и встраивает это прямо в <head>. Остальной CSS грузится асинхронно и никого не держит.
Мы внедрили critical CSS во все проекты на techblog и собрали рабочий воркфлоу: от ручной генерации за 30 секунд до полной автоматизации через Gulp и WordPress-плагины. Ниже, пошаговое руководство без воды.
💡 Быстрый обзор:
- Понять механику блокировки рендеринга и почему браузер ждёт CSS, даже когда HTML уже готов
- Выбрать инструмент под задачу: бесплатный онлайн-генератор за 10 секунд, Penthouse для npm-проектов или связку WP Rocket / Autoptimize для WordPress
- Настроить Gulp-воркфлоу для автоматической перегенерации critical CSS при каждом деплое
- Обойти типовые грабли: FOUC, JS-контент, проблемы с медиа-запросами
Что такое критический CSS и почему браузер тормозит
Браузер строит две структуры: DOM из HTML и CSSOM из стилей. Пока CSSOM не готов, рендеринг стоит на паузе. Это и есть блокирующий CSS, страница остаётся пустой, пока не загрузятся все таблицы стилей из <head>.
Google PageSpeed Insights диагностирует проблему прямо:
У вашей страницы 3 блокирующих CSS-ресурса. Это вызывает задержку при отображении. Ни один элемент верхней части страницы не может быть отрендерен, пока не загрузятся следующие ресурсы.
Термин «above the fold» пришёл из газет. В вебе это видимая область до прокрутки: ~600 px на десктопе, ~900 px на ноутбуке, ~400 px на смартфоне. Большинство разработчиков ориентируются на безопасные 1300 px ширины и 900 px высоты.
Критический CSS, минимальный набор стилей для рендеринга именно этой области. Сетка, навигация, шрифты, верхний блок. Остальное откладывается и грузится асинхронно: страница появляется сразу, а довёрстывается по мере подгрузки.
Цифры ощутимые. По данным Google, встраивание критического CSS сокращает First Contentful Paint на 0,5-1,2 секунды на мобильных устройствах. Для e-commerce это прямо влияет на конверсию: исследование Portent показало, что сайт с FCP менее 1 секунды конвертирует в 3 раза лучше, чем сайт с FCP в 3 секунды.
Инструменты генерации: от бесплатного онлайн до коммерческого API
Сгенерировать критический CSS вручную невозможно, нужен инструмент, который отрендерит страницу в headless-браузере и вытащит только задействованные стили. Вот три работающих варианта.
Инструмент | Тип | Стоимость | Автоматизация | Для кого |
|---|---|---|---|---|
Critical Path CSS Generator | Онлайн | Бесплатно | Нет | Одиночные страницы, старт |
Penthouse | npm-пакет | Бесплатно | Да, через Gulp/скрипты | Разработчики, batch-обработка |
criticalcss.com | SaaS | От $10/мес | Да, API + WordPress | Продакшен, крупные сайты |
Critical Path CSS Generator: онлайн, за 10 секунд
Critical Path CSS Generator Йонаса Олссона, бесплатный инструмент, с которого стоит начать. Интерфейс элементарный: вставляете URL страницы, вставляете ПОЛНЫЙ CSS (хоть 200 КБ минифицированного), нажимаете кнопку, получаете набор стилей для above-the-fold.
Плюс: нулевой порог входа. Не нужны Node.js, npm, скрипты. Минус: чисто ручная работа. Каждую страницу обрабатываете отдельно, при изменении стилей повторяете заново. Для сайта из 5 страниц годится, для 50, уже боль.
Создатель генератора позже запустил коммерческий сервис criticalcss.com, эволюцию той же идеи с автообновлением, валидацией скриншотами и API для batch-обработки.
Penthouse: консольный генератор под Gulp
Penthouse (2680+ звёзд на GitHub), npm-пакет от того же автора. Под капотом Puppeteer и headless-Chromium: открывает страницу, определяет used CSS для заданного viewport и выбрасывает остальное.
Установка:
1 npm install --save-dev penthouse
Минимальный вызов из Node-скрипта:
1 const penthouse = require('penthouse'); 2 const fs = require('fs'); 3 4 penthouse({ 5 url: 'https://example.com', 6 cssString: fs.readFileSync('./style.css', 'utf8'), 7 width: 1300, 8 height: 900 9 }).then(criticalCss => { 10 fs.writeFileSync('./critical.css', criticalCss); 11 });
Ширина 1300 и высота 900, эмпирически безопасные значения. Медиа-запросы шире критического viewport по умолчанию вырезаются. Если нужно сохранить, флаг keepLargerMediaQueries: true.
Важный нюанс: Penthouse запускается с отключённым JavaScript. Если контент above-the-fold генерируется JS-фреймворком, HTML до гидрации пуст, Penthouse не найдёт стилей. Решение: серверный рендеринг (SSR) либо параметр forceInclude с селекторами для принудительного сохранения.
WP Rocket и Autoptimize: два плагина для WordPress
Если сайт на WordPress, ручная генерация critical CSS, избыточный геморрой. Страниц много, шаблоны множатся, стили меняются. Два плагина закрывают задачу полностью.
WP Rocket, премиум-плагин (€59/год за 1 сайт, €119 за 3, €299 за 50). Встроенная опция «Remove Unused CSS» сама генерирует критический CSS для каждой страницы, встраивает в <head>, а остальной CSS загружает асинхронно. Две галочки, и рекомендация «Eliminate render-blocking resources» закрыта. Бонус: встроенный хаб Rocket Insights на базе GTmetrix показывает метрики прямо из админки WordPress.
Autoptimize, бесплатный плагин с опцией «Inline and Defer CSS». Базовая версия генерирует ОДИН файл критического CSS на весь сайт, на практике это не работает (разные страницы, разный above-the-fold). Решение: интеграция с сервисом criticalcss.com (план WordPress, от $10/мес). Плагин автоматически запрашивает критический CSS через API, встраивает и обновляет при изменениях.
Для большинства пользователей WordPress связка WP Rocket или Autoptimize + criticalcss.com закрывает вопрос полностью. Дальше, материал для тех, кто пишет кастомные сайты.

Ручной воркфлоу: генерация, вставка, проверка
Если верстаете сайт без CMS, процесс укладывается в четыре шага.
Шаг 1. Скопируйте ВЕСЬ CSS. Соберите все стили сайта в ОДИН файл. Если пишете на Sass, скомпилируйте. Если фреймворк вроде Bootstrap или Tailwind, включите его CSS полностью. Не гадайте, что «наверное не нужно», генератор сам разберётся.
Шаг 2. Сгенерируйте критический CSS через онлайн-генератор или Penthouse. На выходе, минифицированный блок стилей, который отвечает только за above-the-fold.
Шаг 3. Вставьте критический CSS в <style> внутри <head>. Это принципиально: инлайн-стили не создают дополнительных HTTP-запросов и обрабатываются браузером немедленно. Результат выглядит примерно так:
1 <!DOCTYPE html> 2 <html lang="ru"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <style>@charset "UTF-8";*,*::before,*::after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15}body{margin:0;font-family:'Inter',Helvetica,Arial,sans-serif;font-size:1rem;line-height:1.5;color:#222;background:#fff}nav{display:block}.container{max-width:1200px;margin:0 auto;padding:0 20px}</style> 7 <title>Заголовок страницы</title> 8 </head>
Шаг 4. Вынесите внешние CSS и JS из <head> в низ страницы, перед закрывающим </body>. Да, <link rel="stylesheet"> в футере технически невалиден по спецификации, но на практике работает во всех браузерах и решает проблему блокировки. Альтернатива, loadCSS от Filament Group для асинхронной загрузки стилей без переноса в футер.
Финал, проверка через Google PageSpeed Insights. Рекомендация «Eliminate render-blocking resources» исчезла? Вы всё сделали правильно.
Gulp + Penthouse: автоматизация для проекта без WordPress
Каждое изменение стиля требует перегенерации critical CSS. Делать это вручную, убийственно скучно. Gulp автоматизирует процесс.
Наш продакшен-воркфлоу:
1 // gulpfile.js 2 const gulp = require('gulp'); 3 const penthouse = require('penthouse'); 4 const fs = require('fs'); 5 const urlList = require('./criticalcss-pagelist.json'); 6 7 gulp.task('criticalcss', function () { 8 urlList.urls.forEach(function (item) { 9 penthouse({ 10 url: item.link, 11 css: './css/style.min.css', 12 width: 1300, 13 height: 900, 14 keepLargerMediaQueries: false, 15 renderWaitTime: 100, 16 timeout: 30000 17 }).then(function (criticalCss) { 18 fs.writeFileSync(item.output, criticalCss); 19 console.log('✓ Critical CSS сгенерирован: ' + item.link); 20 }).catch(function (err) { 21 console.error('✗ Ошибка для ' + item.link + ': ' + err.message); 22 }); 23 }); 24 });
Файл criticalcss-pagelist.json со списком URL и выходных файлов:
1 { 2 "urls": [ 3 { "link": "https://example.com", "output": "./critical/home.php" }, 4 { "link": "https://example.com/about", "output": "./critical/about.php" }, 5 { "link": "https://example.com/contact", "output": "./critical/contact.php" } 6 ] 7 }
Вывод пишем в PHP-файлы, они оборачивают CSS и вставляются через include в <head> соответствующего шаблона. Адаптируйте под свой стек: пишите в .css, вставляйте через серверный include, как угодно.
Запуск: gulp criticalcss, и все страницы обработаны за один проход. Вешаете задачу в CI/CD при деплое, и critical CSS всегда актуален.
С какими проблемами вы столкнётесь
Critical CSS, техника не без острых углов. Вот что мы выловили на практике.
Flash of unstyled content (FOUC). Критический CSS не покрыл какой-то элемент, пользователь видит дёргание стилей при полной загрузке. Причина: контент вынесен за пределы viewport через absolute или transform, и генератор его не учёл. Лечение: флаг forceInclude с селектором проблемного элемента.
JS-генерируемый контент. Почти все генераторы (Penthouse, онлайн-инструмент) запускаются с отключённым JavaScript. Если лендинг собран на React, Vue или Angular, а серверного рендеринга нет, HTML пустой, и генератору нечего анализировать. Единственное надёжное решение: включить SSR на уровне фреймворка. Альтернатива, вручную описать селекторы через forceInclude, но это хрупко.
Медиа-запросы. По умолчанию Penthouse вырезает правила, чьи min-width шире заданного viewport. Если не указать keepLargerMediaQueries: true, декстопные стили потеряются, на широком экране сайт «поедет». Всегда проверяйте результат на реальных разрешениях.
Кеширование. Сгенерировали critical CSS, задеплоили, через неделю изменили стиль шапки, а в <head> лежит старая версия. Без автоматизации в CI/CD вы будете забывать перегенерировать. Gulp-таск при деплое решает проблему полностью.
⁉️🤔 Частые вопросы
Обязательно ли использовать Critical CSS на каждом сайте?
Нет, не на каждом. Если у сайта один CSS-файл размером 20 КБ и FCP уже меньше секунды, выгода будет незаметной. Но если в
<head>висит 3-4 таблицы стилей общим весом под 100 КБ, critical CSS даст измеримый прирост. Для лендинга из пары страниц хватит онлайн-генератора за 10 минут. Для магазина на WordPress, WP Rocket с парой галочек. Ориентируйтесь на PageSpeed Insights: если рекомендация «Eliminate render-blocking resources» в топе, делайте.
Можно ли просто перенести все <link> в футер и не париться?
Формально нет, спецификация HTML требует
<link rel="stylesheet">только в<head>. На практике браузеры рендерят страницу и с<link>в футере, но вы получаете вспышку нестилизованного контента (FOUC) до загрузки стилей. Для сайта-визитки допустимо, для коммерческого проекта, нет. Правильный путь: critical CSS в<head>инлайном, асинхронная загрузка остального черезloadCSSилиmedia="print"сonload="this.media='all'". Перенос в футер, костыль, который работает ценой визуального дёргания.
Что изменилось с появлением HTTP/3 и Early Hints?
HTTP/3 и 103 Early Hints позволяют браузеру начать загрузку критических ресурсов до получения полного ответа сервера. Это сокращает задержку, но не отменяет блокировку рендеринга, стили всё равно должны загрузиться и распарситься. Early Hints и critical CSS работают в паре, а не вместо друг друга: Early Hints ускоряет доставку, critical CSS, момент первого рендера. Две техники усиливают друг друга.
Почему Penthouse не обновлялся 4 года, он ещё актуален?
Последний релиз Penthouse (v2.3.3) вышел в 2022 году, но пакет остаётся рабочим: под капотом Puppeteer и Chromium, которые стабильны. Критическая функциональность, генерация used CSS для заданного viewport, не требует частых обновлений. Альтернатива, Critical от Addy Osmani (12 000+ звёзд), который обновляется активнее и тоже интегрируется с Gulp/Grunt.
Как быть с динамическими страницами, где контент зависит от пользователя?
Для страниц с персонализацией (личный кабинет, корзина, дашборд) критический CSS генерируется не для конкретного пользователя, а для общей структуры, шапка, сайдбар, сетка. Динамический контент попадает в асинхронную часть. Если без стилей для пользовательского блока above-the-fold ломается, добавьте соответствующие селекторы через
forceInclude. Генерируйте critical CSS на основе общей структуры страницы, а персонализированные блоки оставляйте в асинхронной загрузке сforceIncludeдля критически важных.
Стоит ли внедрять Critical CSS на вашем проекте
Если сайт загружает больше одного CSS-файла в <head>, critical CSS даст измеримый прирост скорости. Для лендинга из трёх страниц хватит онлайн-генератора за 10 минут. Для блога или магазина на WordPress, две галочки в WP Rocket. Для кастомного проекта, час на настройку Gulp и Penthouse окупается при первом же деплое.
Порог входа ниже, чем кажется. Возьмите бесплатный онлайн-генератор, скопируйте CSS своей страницы, вставьте, и через 30 секунд увидите результат. А когда захотите автоматизации, возвращайтесь к разделу с Gulp-воркфлоу: он закроет вопрос полностью. Ускорение загрузки в 2 раза с парой часов работы, сделка, от которой сложно отказаться.



