Главная Статьи Оптимизация

Критический CSS и рендер-блокировка

Бывает, что файлы сайта уже сжаты и облегчены, а страница всё равно показывается с задержкой — секунду висит белый экран. Чаще всего виновата рендер-блокировка: браузер не рисует страницу, пока не загрузит все стили и часть скриптов. Критический CSS — приём, который убирает эту задержку. Разберём, как он работает.

Что такое рендер-блокировка

Чтобы нарисовать страницу, браузеру нужны стили — иначе он покажет «голый» неоформленный текст, который тут же перерисуется. Поэтому по умолчанию браузер ждёт: сначала качает весь файл CSS, разбирает его, и только потом рисует. Пока CSS грузится — пользователь видит пустоту. То же с обычными скриптами в начале страницы: они тоже останавливают отрисовку. Это и есть рендер-блокировка — ресурсы, которые задерживают первое появление содержимого.

Когда пользователь видит страницу Без оптимизации белый экран — ждёт весь CSS страница С критическим CSS критич. страница полный CSS догружается
Встроенные стили первого экрана показывают страницу сразу, остальное «доезжает» следом.

Идея критического CSS

Хитрость в том, что для показа первого экрана нужна лишь небольшая часть всех стилей — те, что оформляют шапку и видимый блок. Остальное (стили подвала, форм внизу, всплывающих окон) на старте не требуется. Критический CSS — это как раз стили первого экрана, которые встраивают прямо в код страницы, чтобы браузер нарисовал её сразу, не дожидаясь загрузки внешнего файла. А полный CSS подгружают следом, не блокируя отрисовку.

<!-- критичные стили сразу в странице -->
<style> /* стили первого экрана */ </style>
<!-- полный CSS грузится, не блокируя показ -->
<link rel="preload" as="style" href="full.css">

В итоге страница появляется почти мгновенно с правильным оформлением сверху, а остальные стили «доезжают» незаметно.

А что со скриптами

Скрипты блокируют отрисовку так же, как стили. Чтобы они не мешали, к ним добавляют атрибуты defer или async — тогда скрипт грузится, не останавливая показ страницы, и выполняется позже. Тяжёлый JavaScript — одна из главных причин медленной первой отрисовки, и перенос его «вниз» через defer обычно даёт заметный прирост.

⚠️ Не увлекайтесь. Встраивать в страницу весь CSS — плохая идея: код раздуется, потеряется кэширование, и каждая страница станет тяжёлой. В код выносят только критичные стили первого экрана (обычно небольшой объём), а основной файл оставляют внешним — его как раз выгодно кэшировать.

Как это сделать

Вручную выделять критический CSS трудоёмко, поэтому обычно используют автоматические инструменты и плагины оптимизации (на популярных CMS это часто галочка «оптимизировать загрузку CSS» / «устранить рендер-блокировку»). Они сами находят стили первого экрана, встраивают их и откладывают остальное. Это та оптимизация, которую PageSpeed прямо просит фразой «устраните ресурсы, блокирующие отображение».

Критический CSS работает в связке с минификацией и сжатием, а ускоряет он метрики Core Web Vitals — прежде всего время до первой отрисовки и LCP. Общий разбор — как ускорить загрузку сайта.

Как браузер строит страницу

Чтобы понять, почему 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. Делается это обычно автоматическими инструментами и плагинами оптимизации.

Частые вопросы

Что такое рендер-блокировка?
Это ресурсы, которые задерживают первое появление содержимого на экране. По умолчанию браузер не рисует страницу, пока не загрузит и не разберёт все стили (CSS) и блокирующие скрипты в начале страницы. Пока они грузятся, пользователь видит пустой белый экран — это и есть рендер-блокировка.
Что такое критический CSS?
Это стили, которые нужны для отрисовки только первого экрана страницы (шапки и видимого блока). Их встраивают прямо в код страницы, чтобы браузер показал содержимое сразу, не дожидаясь загрузки полного внешнего файла CSS. Остальные стили подгружаются следом, не блокируя отрисовку.
Как ускорить первую отрисовку страницы?
Вынести критический CSS (стили первого экрана) в код страницы, а полный файл стилей грузить асинхронно; добавить скриптам атрибуты defer или async, чтобы они не блокировали показ. Тяжёлый JavaScript — частая причина медленной отрисовки, и перенос его выполнения «вниз» обычно заметно помогает.
Можно ли встроить весь CSS в страницу?
Не стоит. Если встроить весь CSS, код страницы раздуется, пропадёт кэширование общего файла стилей, и каждая страница станет тяжёлой. В код выносят только небольшой критический CSS первого экрана, а основной файл оставляют внешним — его выгодно кэшировать, чтобы повторные визиты были быстрыми.
Как сделать критический CSS на практике?
Вручную это трудоёмко, поэтому обычно используют автоматические инструменты и плагины оптимизации. На популярных CMS есть настройки вроде «устранить рендер-блокировку» или «оптимизировать загрузку CSS» — они сами выделяют стили первого экрана, встраивают их и откладывают остальное. Эту же оптимизацию просит PageSpeed.
Чем отличаются defer и async у скриптов?
async грузит скрипт параллельно и выполняет сразу, как только он готов, без гарантии порядка — подходит для независимых счётчиков аналитики. defer тоже грузит параллельно, но выполняет после полного разбора HTML и строго в порядке подключения — безопасный выбор для скриптов, зависящих от страницы. Правило: большинству скриптов defer, независимым счётчикам async.
Как обнаружить рендер-блокировку?
Через PageSpeed Insights или Lighthouse: пункт «Устраните ресурсы, блокирующие отображение» прямо перечисляет файлы CSS и JS, задерживающие показ. Связанная метрика — FCP (время до первого содержимого). Если есть жалоба на блокирующие ресурсы и высокий FCP, пора заняться критическим CSS и defer-скриптами.