CSS блокирует рендер страницы
Большой CSS-файл задерживает First Contentful Paint. Critical CSS, defer, разделение.
Симптом
- First Contentful Paint (FCP) значительно выше, чем обычно (более 3 с).
- В DevTools → Network виден один большой CSS‑файл, который загружается до рендера.
- Пользователь видит «пустую» страницу, пока не загрузится весь CSS.
- В консоли браузера нет ошибок, но в Performance‑панели видно, что «Stylesheet» занимает большую часть времени.
- На мобильных устройствах страница «плотно» блокируется, пока не применятся стили.
Причина
Большой CSS‑файл блокирует рендер, потому что браузер не может отрисовать страницу, пока не загрузит и не проанализирует все стили. Это происходит из‑за:
1. Синхронной загрузки <link rel="stylesheet"> в <head>. Браузер ставит загрузку в очередь и не продолжает рендер до её завершения.
2. Отсутствия критического CSS (critical CSS). Если стили, необходимые для верхней части страницы, находятся в конце файла, браузер ждёт, пока загрузится весь файл.
3. Отсутствия атрибута rel="preload" или rel="prefetch" для предварительной загрузки.
4. Отсутствия атрибута media="print" для стилей, которые не нужны сразу.
Как проверить
- Performance‑панель DevTools
- Открой DevTools → Performance → Record.
- Сохрани запись, пока страница загружается.
- Посмотри, сколько времени занимает «Stylesheet» и «Layout». - Network‑панель
- Убедись, что CSS‑файл загружается синхронно (blockingв колонкеStatus).
- Посмотри размер файла и время загрузки. - Проверка критического CSS
- В Chrome DevTools → Coverage → Start instrumenting coverage.
- Сохрани страницу и посмотри, какие стили используются в видимой части.
- Если большая часть стилей не используется, это сигнал к разделению. - Проверка атрибутов
- В исходном коде ищи<link rel="stylesheet" href="...">.
- Если нетrel="preload"илиmedia="print", это может быть причиной блокировки.
Решение
1. Разделить CSS на критический и не‑критический
<head>
<!-- Критический CSS вlined -->
<style>
/* critical.css */
body { margin:0; font-family:Arial, sans-serif; }
.header { background:#333; color:#fff; padding:10px; }
/* ... остальные стили, которые нужны сразу */
</style>
<!-- Остальной CSS загружается асинхронно -->
<link rel="preload" href="/css/main.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/css/main.css"></noscript>
</head>
rel="preload"позволяет браузеру начать загрузку сразу, но не блокировать рендер.onload="this.rel='stylesheet'"переключает тип после загрузки.noscriptобеспечивает поддержку без JavaScript.
2. Использовать media="print" для стилей, которые нужны только после рендера
<link rel="stylesheet" href="/css/print.css" media="print">
3. Минимизировать размер CSS
- Удалить неиспользуемые правила (например, с помощью PurgeCSS).
- Сжать файл (gzip, Brotli).
- Сконкатенировать небольшие файлы в один, если они нужны сразу.
4. Установить async/defer для JavaScript, который загружает стили
Если стили генерируются динамически, используйте async:
<script async src="/js/dynamic-styles.js"></script>
5. Проверить результаты
- После изменений снова запусти Performance‑панель.
- Убедись, что «Stylesheet» занимает < 500 мс и FCP улучшился до 1–1.5 с.
Связанные
Не хотите разбираться сами?
Запустите технический аудит сайта за 5 минут — получите PDF-отчёт с разбором всех 64 параметров и конкретными точками роста. Или закажите комплексное SEO-продвижение сайта — починим всё это и возьмём на себя дальнейшую оптимизацию.