CSS для Web Vitals
Методы оптимизации Web Vitals, связанные с CSS
Приемы, используемые при написании стилей и создании макетов, могут значительно влиять на метрики Core Web Vitals. Это особенно справедливо для метрик Cumulative Layout Shift (CLS) (Совокупное смещение макета) и Largest Contentful Paint (LCP) (Отображение самого крупного элемента содержимого).
В этой статье рассказывается о методах оптимизации Web Vitals, связанных с CSS. Эти методы разделены на группы по различным аспектам страниц: макетам, изображениям, шрифтам, анимации и загрузке. Попутно мы расскажем, как улучшить следующий пример страницы:

Макет #
Вставка контента в DOM #
При добавлении контента на страницу после того как окружающий контент уже загружен, содержимое страницы сдвигается вниз. Это приводит к сдвигам макета.
Распространенный пример такой проблемы — уведомления о файлах cookie (особенно размещенные в верхней части страницы). Среди прочих элементов страницы, которые часто приводят к таким сдвигам макета при загрузке, — рекламные объявления и внедренные элементы.
Выявление проблемы #
С помощью аудита Avoid large layout shifts в в Lighthouse можно выявить сдвинутые элементы страницы. Для нашей демонстрации результаты выглядят следующим образом:

В этих результатах не указано уведомление о файлах cookie, так как оно не сдвигается при загрузке. Тем не менее при его отображении смещаются расположенные под ним элементы (то есть div.hero
и article
) на странице. Дополнительные сведения о выявлении сдвигов макета и их устранении см. в статье «Устранение сдвигов макета».
Решение проблемы #
Разместите уведомление о файлах cookie в нижней части страницы, используя абсолютное или фиксированное позиционирование.

Было:
.banner {
position: sticky;
top: 0;
}
Стало:
.banner {
position: fixed;
bottom: 0;
}
Другой способ предотвратить смещение макета — зарезервировать место для уведомления о файлах cookie в верхней части экрана. Это тоже эффективный подход. Дополнительные сведения см. в статье «Рекомендации по уведомлениям о файлах cookie».
Изображения #
Изображения и метрика Largest Contentful Paint (LCP) #
Обычно изображения — самые крупные отображаемые элементы содержимого на странице. Перечень других элементов страницы, которые могут быть самыми крупными отображаемыми элементами содержимого, включает блоки текста и изображения элементов poster для видео. Метрика LCP зависит от времени загрузки самого крупного отображаемого элемента содержимого.
Важно отметить, что при каждой загрузке страницы самым крупным отображаемым элементом содержимого могут быть разные элементы в зависимости от того, какое содержимое видит пользователь при первом отображении страницы. Например, в нашей демонстрации потенциальные самые крупные отображаемые элементы содержимого — фон уведомления о файлах cookie, главное изображение и текст статьи.

В нашем примере сайта фоновое изображение уведомления о файлах cookie имеет большой размер. Чтобы улучшить метрику LCP и при этом создать нужный эффект, можно нарисовать градиент в CSS, а не загружать изображение.
Решение проблемы #
Измените элемент CSS .banner
и используйте градиент CSS, а не изображение.
Было:
background: url("https://cdn.pixabay.com/photo/2015/07/15/06/14/gradient-845701\_960\_720.jpg")
Стало:
background: linear-gradient(135deg, #fbc6ff 20%, #bdfff9 90%);
Изображения и сдвиги макета #
Браузеры могут определять размер изображений только после их загрузки. Если загрузка изображения выполняется после рендеринга страницы и при этом для изображения не зарезервировано место, то при отображении изображения произойдет сдвиг макета. В нашей демонстрации загрузка главного изображения приводит к сдвигу макета.
Выявление проблемы #
Выявить изображения без явно заданных атрибутов width
и height
можно с помощью аудита Image elements have explicit width and height в Lighthouse.

В этом примере и у главного изображения, и у изображения статьи отсутствуют атрибуты width
и height
.
Решение проблемы #
Чтобы не допустить сдвиги макета, настройте атрибуты width
и height
для этих изображений.
Было:
<img src="https://source.unsplash.com/random/2000x600" alt="Изображение, которое необходимо загрузить">
<img src="https://source.unsplash.com/random/800x600" alt="Изображение, которое необходимо загрузить">
Стало:
<img src="https://source.unsplash.com/random/2000x600" width="2000" height="600" alt="Изображение, которое необходимо загрузить">
<img src="https://source.unsplash.com/random/800x600" width="800" height="600" alt="Изображение, которое необходимо загрузить">
Шрифты #
Шрифты могут задерживать рендеринг текста и приводить к сдвигам макета. Таким образом, важно быстро доставлять их.
Отложенный рендеринг текста #
По умолчанию браузер не сразу отображает элемент text, если связанные с ним веб-шрифты еще не загружены. Это сделано, чтобы предотвратить «мигание текста без стиля« (FOUT). Во многих ситуациях это приводит к задержке первого отображения содержимого (First Contentful Paint [FCP]), а в некоторых ситуациях — к задержке при отображении самого крупного элемента содержимого (Largest Contentful Paint [LCP]).
Сдвиги макета #
Метод с заменой шрифта отлично подходит, если нужно быстро отображать содержимое для пользователя, но может привести к сдвигу макета. Такие сдвиги макета возникают, когда веб-шрифт и используемый вместо него резервный шрифт занимают разное место на странице. Используя шрифты с похожими пропорциями, можно свести к минимуму сдвиги макета.

Выявление проблемы #
Чтобы посмотреть, какие шрифты загружаются на определенной странице, в Devtools откройте вкладку Network (Сеть) и выполните фильтрацию по полю Font (Шрифт). Файлы шрифтов могут иметь большой размер, поэтому для повышения производительности, как правило, лучше использовать меньшее количество шрифтов.

Узнать, сколько времени требуется на запрос шрифта, можно на вкладке Timing (Время). Чем раньше будет запрошен шрифт, тем скорее он будет загружен и использован.

Посмотреть цепочку запросов на шрифт можно на вкладке Initiator (Инициатор). Вообще говоря, чем короче цепочка запросов, тем быстрее можно запросить шрифт.

Решение проблемы #
В нашей демонстрации используется API Google Fonts. Google Fonts позволяет загружать шрифты с помощью тегов <link>
или оператора @import
. Фрагмент кода тега <link>
включает подсказку ресурса preconnect
. Это должно привести к более быстрой доставке таблиц стилей, чем при использовании версии с оператором @import
.
На очень высоком уровне можно считать подсказки ресурсов способом сообщить браузеру, что ему потребуется настроить определенное соединение или загрузить определенный ресурс. В результате браузер сделает эти действия приоритетными. При использовании подсказок ресурсов имейте в виду, что если сделать определенное действие приоритетным, это отнимет часть ресурсов браузера, которые можно было бы потратить на другие действий. Таким образом, подсказки ресурсов следует использовать вдумчиво и не для всего подряд. Дополнительные сведения см. в статье «Заблаговременное создание сетевых подключений для повышения воспринимаемой скорости работы страницы».
Удалите из таблицы стилей следующий оператор @import
:
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400&family=Roboto:wght@300&display=swap');
В элемент <head>
документа добавьте следующие теги <link>
:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">
Эти теги link сообщают браузеру, что нужно заблаговременно создать подключение к источникам, используемым Google Fonts, и загрузить таблицу стилей, содержащую объявления для шрифтов Montserrat и Roboto. Такие теги <link>
следует размещать как можно раньше в элементе <head>
.
Анимации #
В основном, анимации влияют на метрики Web Vitals, если они приводят к сдвигу макета. Старайтесь не использовать анимации двух типов: анимации, изменяющие макет, и эффекты, «похожие на анимацию», при которых выполняется перемещение элементов страницы. Обычно такие анимации можно заменить более производительными эквивалентами, используя ряд свойств CSS, например transform
, opacity
и filter
. Дополнительные сведения см. в статье «Как создавать высокопроизводительные CSS-анимации».
Выявление проблемы #
Анимации с низкой производительностью можно выявлять c помощью аудита Avoid non-composited animations в Lighthouse.

Решение проблемы #
Измените последовательность анимации slideIn
и используйте функцию transform: translateX()
, а не переход с использованием свойства margin-left
.
Было:
.header {
animation: slideIn 1s 1 ease;
}
@keyframes slideIn {
from {
margin-left: -100%;
}
to {
margin-left: 0;
}
}
Стало:
.header {
animation: slideIn 1s 1 ease;
}
@keyframes slideIn {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
Критически важный код CSS #
Таблицы стилей блокируют рендеринг. Это означает, что когда браузер встречает таблицу стилей, он перестает загружать другие ресурсы, пока не загрузит и не проанализирует ее. Это может приводить к задержкам при загрузке самых крупных отображаемых элементов содержимого. Чтобы повысить производительность, можно удалить неиспользуемый код CSS, встроить критически важный код CSS и отложить выполнение кода CSS, который не является критически важным.
Вывод #
Несмотря на то что возможности для дальнейшей оптимизации страницы не исчерпаны (например, можно сжимать изображения, чтобы быстрее доставлять их), выполненные изменения значительно улучшили метрики Web Vitals для этого сайта. Если бы это был настоящий сайт, на следующем этапе следовало бы собрать данные о производительности от реальных пользователей, чтобы оценить, соответствует ли сайт пороговым значениям метрик Web Vitals для большинства пользователей. Дополнительные сведения о Web Vitals см. в статье «Изучение Web Vitals».