---
layout: post
title: Извлечение критического CSS-кода
subhead: Узнайте, как улучшить время рендеринга благодаря извлечению критического CSS-кода.
authors:
  - mihajlija
date: 2019-05-29
hero: image/admin/ZC6iWHhgnrSZtPJMfwMh.jpg
alt: Фото гаечных ключей и отверток, разложенных на поверхности.
description: Узнайте, как улучшить время рендеринга благодаря извлечению критического CSS-кода, а также как выбрать наилучший инструмент для своего проекта.
codelabs: codelab-extract-and-inline-critical-css
tags:
  - blog
  - performance
  - css
---

CSS-файлы — это ресурс, блокирующий рендеринг: браузер должен загрузить и обработать их, прежде чем сможет отобразить страницу. Если загрузка CSS-файлов занимает много времени из-за их большого размера или плохого качества соединения, время рендеринга веб-страницы может существенно увеличиться.

{% Aside 'key-term' %} Критический CSS-код — это методика, при использовании которой CSS-код, необходимый для отображения изначально видимой области, извлекается, чтобы позволить как можно быстрее отобразить пользователю контент. {% endAside %}

<figure> {% Img src="image/admin/t3Kkvh265zi6naTBga41.png", alt="Иллюстрация ноутбука и мобильного устройства с веб-страницей, выходящей за пределы экрана", width="800", height="469", class="" %}</figure>

{% Aside 'note' %} Изначально видимая область — это область, которую пользователь видит сразу после загрузки страницы, не совершая прокрутку. Изначально видимая область не имеет универсально определенной высоты в пикселях, так как существует множество устройств с различным размером экрана. {% endAside %}

Извлечение стилей и встраивание их в раздел `<head>` HTML-документа позволяет загружать их, не совершая дополнительных запросов. Остальная часть CSS-кода может быть загружена в асинхронном режиме.

<figure> {% Img src="image/admin/RVU3OphqtjlkrlAtKLEn.png", alt="HTML-файл с критическим CSS-кодом, встроенным в раздел head", width="800", height="325" %} <figcaption> Встраивание критического CSS-кода </figcaption></figure>

Улучшение времени рендеринга может существенно повлиять на [воспринимаемую производительность](/rail/#focus-on-the-user), особенно при плохом качестве соединения. Для мобильных сетей характерны высокие задержки независимо от пропускной способности.

<figure> {% Img src="image/admin/NdQz49RVgdHoh3Fff0yr.png", alt="Покадровое сравнение загрузки через 3G-соединение страницы с CSS-кодом, блокирующим рендеринг (сверху), и той же страницы, но со встроенным критическим CSS-кодом (снизу). В верхней последовательности контент начинает отображаться только после шести пустых кадров. В нижней последовательности осмысленный контент отображается уже в первом кадре.", width="800", height="363" %} <figcaption> Сравнение загрузки через 3G-соединение страницы с CSS-кодом, блокирующим рендеринг (сверху), и той же страницы, но со встроенным критическим CSS-кодом (снизу) </figcaption></figure>

Если у вас плохой показатель [первой отрисовки контента (FCP)](/fcp/) и в отчете Lighthouse показывается рекомендация «Eliminate render-blocking resource» («Устраните ресурсы, блокирующие рендеринг»), вам стоит попробовать методику критического CSS-кода.

{% Img src="image/admin/0xea7menL90lWHwbjZoP.png", alt="Проверка Lighthouse с рекомендациями «Eliminate render-blocking resource» или «Defer unused CSS»", width="743", height="449" %}

{% Aside 'gotchas' %} Помните, что встраивание на страницу большого объема CSS-кода замедляет загрузку остальной части HTML-документа. Нельзя сделать приоритетным весь контент сразу. Кроме того, встраивание кода чревато тем, что браузер не сможет кешировать CSS для дальнейшего использования при загрузке страниц, так что не следует злоупотреблять им. {% endAside %}

<p id="14KB">Чтобы минимизировать число запросов при первом рендеринге, старайтесь, чтобы размер контента в изначально видимой области не превышал <strong>14 КБ</strong> (в сжатом виде).</p>

{% Aside 'note' %} Новые [TCP](https://hpbn.co/building-blocks-of-tcp/)-соединения не могут сразу же использовать всю доступную полосу пропускания между клиентом и сервером; соединение происходит с [медленным стартом](https://hpbn.co/building-blocks-of-tcp/#slow-start), чтобы избежать перегрузки соединения чрезмерно большим объемом данных. При таком подходе сервер начинает передачу с небольшого объема данных и, если данные достигают клиента в идеальном состоянии, удваивает объем при следующей отправке. Большинство серверов могут отправить при первой передаче не больше 10 пакетов или примерно 14 КБ. {% endAside %}

Влияние этого метода на производительность зависит от конкретного типа сайта. Как правило, чем больше на сайте CSS-кода, тем более серьезного эффекта можно добиться при помощи встраиваемого CSS-кода.

## Обзор инструментов

Существует несколько отличных инструментов, которые автоматически определяют критический CSS-код на странице. Это хорошая новость, поскольку вручную это делать было бы слишком утомительно. Для определения стилей, распространяющихся на каждый элемент в области просмотра, требуется анализ всей структуры DOM.

### Critical

[Critical](https://github.com/addyosmani/critical) извлекает, минифицирует и встраивает CSS-код, относящийся к изначальной видимой области. Он доступен в виде [модуля npm](https://www.npmjs.com/package/critical). Его можно использовать с Gulp (напрямую) или с Grunt (как [плагин](https://github.com/bezoerb/grunt-critical)); кроме того, есть и [плагин webpack](https://github.com/anthonygore/html-critical-webpack-plugin).

Этот простой инструмент позволяет сэкономить массу усилий. Вам даже не нужно указывать таблицы стилей: Critical автоматически их обнаружит. Он также поддерживает извлечение критического CSS-кода для различных разрешений экрана.

### criticalCSS

[CriticalCSS](https://github.com/filamentgroup/criticalCSS) — еще один [npm-модуль](https://www.npmjs.com/package/criticalcss) для извлечения CSS, относящегося к изначальной видимой области. Он также доступен в виде инструмента командной строки.

Он не поддерживает встраивание и минификацию, однако позволяет принудительно включать правила, не являющиеся частью критического CSS-кода, и дает более тонкий контроль над включением деклараций `@font-face`.

### Penthouse

[Penthouse](https://github.com/pocketjoso/penthouse) — хороший выбор, если сайт или приложение используют большое количество стилей или если стили динамически внедряются в DOM (как часто бывает в приложениях Angular). Он основан на [Puppeteer](https://github.com/GoogleChrome/puppeteer), и у него есть [онлайн-версия](https://jonassebastianohlsson.com/criticalpathcssgenerator/).

Penthouse не определяет таблицы стилей автоматически; файлы HTML и CSS, для которых требуется создать критический CSS-код, необходимо указывать вручную. Плюс инструмента в том, что он хорошо справляется с параллельным выполнением нескольких задач.
