«Встройте критический CSS прямо в страницу» — один из самых частых советов PageSpeed. Мы пробовали это несколько раз. Дважды стало хуже, один раз — заметно лучше. Эта статья — честный рассказ обо всех попытках и о том, почему результат зависит не от самого приёма, а от того, что именно держит отрисовку.
Это двадцать девятая часть цикла «PageSpeed без мифов».
Неудачные попытки
На двух проектах мы встраивали критический CSS в страницу — и оба раза оценка становилась хуже, после чего мы откатывали правку. Скажем прямо: подробных замеров тех попыток у нас не сохранилось, только вывод «хуже, откатить». Поэтому не будем выдумывать цифр. Одно известно точно: тогда мы ещё не разбирали окно первой отрисовки — эта методика появилась позже. А вот обычные причины, по которым инлайн делает хуже:
- CSS не узкое место. Если в окне первой отрисовки лежат шрифты и картинки — сотни килобайт и секунды по формуле, — инлайн убирает один запрос, но утяжеляет HTML, который грузится первым, и на фоне главной проблемы даёт чистый минус.
- Встраиваемая часть большая. Чем больше CSS в HTML, тем позже браузер получает сам документ и тем больше повторяется на каждой странице: внешний CSS кэшируется браузером один раз, встроенный — качается с каждой страницей заново.
- Граница «критического» неточная. Если встроенная часть не покрывает первый экран полностью, страница рисуется «полуготовой», а потом перестраивается — это сдвиги вёрстки.
Урок: сначала очистить окно первой отрисовки (шрифты, видео, картинки, сторонние скрипты — предыдущие части цикла), и только потом смотреть на CSS.
Удачная попытка
Позже, на другом сайте, ситуация была другой: окно первой отрисовки уже чистое, шрифты и картинки разобраны, сторонние скрипты отложены. Товарная страница застряла на 80. Разбор трассы показал:
- главный поток до отрисовки занят всего 42 мс — скрипты не мешают;
- зато цепочка «документ (293 мс) → стили (264 мс)» — последовательная: пока стили не пришли, рисовать нечего.
Отчёт PageSpeed обещал от устранения блокирующих ресурсов всего 150 мс. Мы проверили на копии страницы:
| Стили отдельным файлом | Стили в странице | |
|---|---|---|
| оценка | 80 | 88 |
| Speed Index | 3,4 с | 2,3 с |
| первая отрисовка | 1286 мс | 209 мс |
Эффект оказался намного больше, чем обещал отчёт: дело было не в весе стилей, а в лишнем круге сетевой задержки, который в модели PageSpeed стоит дорого.
Резать CSS не обязательно
Перед инлайном мы проверили, не проще ли уменьшить сам CSS. Разобрали чанк по компонентам (разбить по закрывающей скобке и сгруппировать по первому классу селектора): стили слайдера — 6 КБ, стили галереи — 2 КБ, а вычистить можно было 1,5–2 КБ из 31 КБ сжатых. То есть дело не в весе: даже идеально вычищенный файл всё равно приходит отдельным кругом.
// быстрый разбор CSS-файла: какие компоненты сколько весят
const css = require("fs").readFileSync("main.css", "utf8");
const by = {};
css.split("}").forEach(rule => {
const sel = (rule.split("{")[0] || "").trim();
const key = (sel.match(/\.[\w-]+/) || ["(без класса)"])[0];
by[key] = (by[key] || 0) + rule.length + 1;
});
Object.entries(by).sort((a, b) => b[1] - a[1]).slice(0, 15)
.forEach(([k, v]) => console.log(k.padEnd(30), (v / 1024).toFixed(1), "КБ"));
Когда инлайн выигрывает, а когда нет
| Ситуация | Инлайн критического CSS |
|---|---|
| в окне первой отрисовки тяжёлые шрифты, видео, картинки | не делать: лечите их — эффект будет в разы больше |
| окно чистое, главный поток свободен, отрисовку держит цепочка «документ → стили» | делать: это следующий честный шаг |
| CSS большой, а критическая часть первого экрана — небольшая | встраивать только первый экран (обычно 5–10 КБ), остальное — отдельным файлом |
| стили сильно отличаются на разных страницах | генерировать критическую часть при сборке для каждого типа страниц |
Проверяйте на копии страницы серией прогонов. Оба наших неудачных опыта начинались с «советует же PageSpeed». Удачный — с A/B, где мы видели цифры до выката.
Думаете о встраивании CSS?
Пришлите адрес — проверю, что держит отрисовку, и скажу, даст ли инлайн что-нибудь вашей странице.
// загружаю комментарии…