Критический CSS и рендер-блокировка
Бывает, что файлы сайта уже сжаты и облегчены, а страница всё равно показывается с задержкой — секунду висит белый экран. Чаще всего виновата рендер-блокировка: браузер не рисует страницу, пока не загрузит все стили и часть скриптов. Критический CSS — приём, который убирает эту задержку. Разберём, как он работает.
Что такое рендер-блокировка
Чтобы нарисовать страницу, браузеру нужны стили — иначе он покажет «голый» неоформленный текст, который тут же перерисуется. Поэтому по умолчанию браузер ждёт: сначала качает весь файл CSS, разбирает его, и только потом рисует. Пока CSS грузится — пользователь видит пустоту. То же с обычными скриптами в начале страницы: они тоже останавливают отрисовку. Это и есть рендер-блокировка — ресурсы, которые задерживают первое появление содержимого.
Идея критического CSS
Хитрость в том, что для показа первого экрана нужна лишь небольшая часть всех стилей — те, что оформляют шапку и видимый блок. Остальное (стили подвала, форм внизу, всплывающих окон) на старте не требуется. Критический CSS — это как раз стили первого экрана, которые встраивают прямо в код страницы, чтобы браузер нарисовал её сразу, не дожидаясь загрузки внешнего файла. А полный CSS подгружают следом, не блокируя отрисовку.
<style> /* стили первого экрана */ </style>
<!-- полный CSS грузится, не блокируя показ -->
<link rel="preload" as="style" href="full.css">
В итоге страница появляется почти мгновенно с правильным оформлением сверху, а остальные стили «доезжают» незаметно.
А что со скриптами
Скрипты блокируют отрисовку так же, как стили. Чтобы они не мешали, к ним добавляют атрибуты defer или async — тогда скрипт грузится, не останавливая показ страницы, и выполняется позже. Тяжёлый JavaScript — одна из главных причин медленной первой отрисовки, и перенос его «вниз» через defer обычно даёт заметный прирост.
Как это сделать
Вручную выделять критический CSS трудоёмко, поэтому обычно используют автоматические инструменты и плагины оптимизации (на популярных CMS это часто галочка «оптимизировать загрузку CSS» / «устранить рендер-блокировку»). Они сами находят стили первого экрана, встраивают их и откладывают остальное. Это та оптимизация, которую PageSpeed прямо просит фразой «устраните ресурсы, блокирующие отображение».
Как браузер строит страницу
Чтобы понять, почему CSS блокирует показ, полезно знать, как браузер вообще рисует страницу. Сначала он скачивает HTML и строит из него дерево элементов (DOM). Параллельно ему нужны стили: из CSS он строит дерево стилей (CSSOM). Нарисовать страницу можно только когда есть и то, и другое — браузер объединяет их в дерево отрисовки и выводит на экран. Вот почему CSS блокирующий: без полного набора стилей браузер не знает, как всё выглядит, и предпочитает подождать, чем показать «голый» текст, который через миг перерисуется. Этот путь от файлов до пикселей называют критическим путём рендеринга, и задача оптимизации — сделать его как можно короче.
defer и async: в чём разница
Оба атрибута снимают блокировку со скриптов, но ведут себя по-разному. Обычный скрипт без атрибутов останавливает разбор HTML: браузер натыкается на него, бросает всё, грузит и выполняет скрипт, и только потом продолжает. async грузит скрипт параллельно и выполняет сразу, как только тот готов, не дожидаясь остального; порядок выполнения при этом не гарантирован — подходит для независимых скриптов вроде счётчиков аналитики. defer тоже грузит параллельно, но выполняет уже после полного разбора HTML и строго в порядке подключения — безопасный выбор для скриптов, которые зависят от страницы или друг от друга. Простое правило: для большинства скриптов берите defer, для независимых счётчиков — async.
Подсказки ресурсам: preload и preconnect
Браузеру можно помочь, заранее подсказав, что загрузить. preload говорит «этот ресурс точно понадобится скоро — начни качать его раньше», и его применяют к тому самому полному CSS или ключевому шрифту. preconnect заранее устанавливает соединение с внешним доменом (например, со шрифтами или аналитикой), чтобы потом не тратить время на рукопожатие. Эти подсказки не уменьшают объём, но меняют порядок и тайминг загрузки в вашу пользу. Подробнее — в статье про preload и preconnect.
Чем измерить рендер-блокировку
Понять, есть ли проблема, помогают инструменты замера скорости — PageSpeed Insights и встроенный в браузер Lighthouse. Они прямо называют виновников: пункт «Устраните ресурсы, блокирующие отображение» перечисляет конкретные файлы CSS и JS, которые задерживают показ. Связанная метрика — FCP (First Contentful Paint), время до появления первого содержимого: чем раньше, тем лучше. Если PageSpeed жалуется на блокирующие ресурсы, а FCP высокий, — это сигнал заняться критическим CSS и defer-скриптами. После правок перепроверьте там же.
Коротко
Рендер-блокировка — это когда браузер не показывает страницу, пока не загрузит все стили и блокирующие скрипты, и пользователь видит белый экран. Критический CSS убирает задержку: стили первого экрана встраивают прямо в код, чтобы страница отрисовалась сразу, а полный CSS и скрипты грузят следом, не блокируя показ (скрипты — через defer/async). Главное — выносить в код только критичные стили, а не весь CSS. Делается это обычно автоматическими инструментами и плагинами оптимизации.