Блокирующий ресурс (Render-Blocking Resource) — это любой внешний файл, который браузер должен загрузить, обработать и выполнить (или применить), прежде чем сможет отобразить страницу. Ключевая цель веб-производительности — минимизировать время блокировки (Blocking Time). Устранение этих ресурсов напрямую улучшает метрики FCP (First Contentful Paint), LCP (Largest Contentful Paint) и INP (Interaction to Next Paint).
Блокировка происходит, потому что браузер должен создать две модели, прежде чем что-либо показать: DOM (Document Object Model) из HTML и CSSOM (CSS Object Model) из стилей.
1. Главные виновники и их методы устранения
| Виновник | Почему блокирует | Ключевая метрика | Метод устранения |
|---|---|---|---|
| CSS (внешние файлы) | Браузер не может построить CSSOM до загрузки всех стилей. | FCP, LCP | Инлайнинг критического CSS и асинхронная загрузка остального. |
| JavaScript | Блокирует парсинг HTML и выполнение в главном потоке. | LCP, INP, TBT | Использование атрибутов defer или async. |
| Веб-шрифты | Вызывают невидимый текст (FOIT) или вспышку нестилизованного текста (FOUT). | CLS, LCP | Использование font-display: swap и preload. |
2. Ключевая 4-шаговая стратегия устранения блокировки
Чтобы эффективно устранить все блокирующие ресурсы, необходимо следовать четкой последовательности действий, которая позволяет браузеру быстро приступить к рендерингу.
Шаг 1: Инлайнинг Критического CSS
Это самый важный шаг для ускорения FCP. Вместо того чтобы заставлять браузер ждать сетевого запроса для загрузки внешнего файла CSS, мы предоставляем ему минимальные стили для первого экрана непосредственно в <head>.
<head>
<!-- Инлайнинг (Встроенный) Критический CSS, ~5-15 КБ -->
<style>
.header { /* ... стили для шапки ... */ }
/* ... */
</style>
<!-- ... -->
</head>
Шаг 2: Асинхронная загрузка некритического CSS
Остальной CSS, который не нужен для первого экрана, должен быть загружен в фоновом режиме.
Используйте “LoadCSS Trick” — установку атрибута media="print" (заставляя браузер считать файл неблокирующим) с последующим переключением на media="all" с помощью JavaScript после загрузки.
<link rel="stylesheet"
href="all-styles.css"
media="print"
onload="this.media='all'">
Шаг 3: Деферринг (Deferring) и Асинхронная Загрузка JS
Переведите все ваши скрипты в неблокирующий режим.
- Используйте
deferдля основных скриптов приложения, которые зависят от DOM или порядка выполнения. Они загружаются параллельно и выполняются после парсинга HTML. - Используйте
asyncдля независимых сторонних скриптов (аналитика, реклама), которые выполняются сразу после загрузки, приостанавливая парсинг HTML.
<!-- app.js требует DOM, поэтому используем defer -->
<script defer src="app.js"></script>
<!-- analytics.js независим, поэтому используем async -->
<script async src="analytics.js"></script>
Шаг 4: Оптимизация шрифтов
Убедитесь, что загрузка шрифтов не приводит к невидимости текста.
- Используйте
font-display: swapв@font-face, чтобы браузер временно отобразил текст системным шрифтом, пока не загрузится нужный. Это устраняет FOIT (Flash of Invisible Text). - Используйте
<link rel="preload">для ранней загрузки самых важных файлов шрифтов, чтобы они были доступны, когда браузер начнет рендеринг.
3. Секретное оружие: Подсказки браузеру (Resource Hints)
Resource Hints — это мощные директивы, которые вы размещаете в <head>, чтобы дать браузеру указания о том, какие ресурсы будут нужны в ближайшем будущем. Они позволяют начать сетевые операции как можно раньше, не блокируя при этом рендеринг.
| Подсказка | Когда использовать | Эффект |
|---|---|---|
preconnect | Для доменов, с которых вы будете загружать критические сторонние ресурсы (CDN, API, аналитика). | Выполняет DNS-запрос, TCP-рукопожатие и TLS-согласование заранее. Экономит до 100-500 мс. |
preload | Для критических ресурсов, которые будут использованы на текущей странице, но их обнаружение может занять время (например, шрифты, которые находятся глубоко в CSS). | Браузер немедленно начинает загрузку ресурса с высоким приоритетом. |
prefetch | Для ресурсов, которые, скорее всего, понадобятся пользователю на следующей странице. | Загружает ресурс с низким приоритетом, чтобы кэшировать его для следующего перехода. |
Примеры использования Resource Hints
<!-- 1. preconnect: Установим соединение с доменом аналитики/CDN -->
<link rel="preconnect" href="[https://example-cdn.com](https://example-cdn.com)">
<!-- 2. preload: Принудительно загружаем критический шрифт (если он нужен для LCP-элемента) -->
<link rel="preload" href="/fonts/montserrat-bold.woff2" as="font" type="font/woff2" crossorigin>
<!-- 3. prefetch: Загружаем ресурс для возможной следующей страницы -->
<link rel="prefetch" href="/next-page-data.json" as="fetch">
Используйте preconnect для сторонних доменов и preload для критических ресурсов, которые вы хотите получить быстрее, чем браузер сможет их обнаружить естественным путем.
4. Оптимизация на уровне доставки
Несмотря на все усилия по управлению блокировкой, если файл большой, он все равно будет дольше загружаться.
- Сжатие (Compression): Убедитесь, что ваш сервер использует алгоритмы сжатия Brotli (предпочтительнее) или Gzip. Это уменьшает размер всех текстовых файлов (HTML, CSS, JS) на 70-80%.
- HTTP-Кэширование: Настройте заголовки Cache-Control и Expires для статических ресурсов (CSS, JS, изображения), чтобы браузер мог повторно использовать их при последующих посещениях, избегая повторной загрузки.
- HTTP/2 (и HTTP/3): Современные протоколы позволяют браузеру выполнять множество параллельных запросов по одному соединению, что значительно ускоряет загрузку всех ресурсов после устранения блокировки.
Вывод
Устранение блокирующих ресурсов — это не одно действие, а комплексная стратегия, направленная на оптимизацию Критического Пути Рендеринга. Применяя инлайнинг, деферринг и Resource Hints, вы гарантируете, что браузер получает только самое необходимое для первого экрана и может начать отображение в течение первых 1-2 секунд.
Основной принцип: Ни один ресурс, кроме HTML, не должен блокировать рендеринг первого экрана, если это не абсолютно критический инлайновый CSS.