В прошлой статье мы рассмотрели три основные показателя нового критерия ранжирования Google — Core Web Vitals, предназначенных для измерения пользовательского опыта работы с сайтом. В этой статье я расскажу, что мы делаем для улучшения веб-производительности во время разработки.
Largest Contentful Paint (LCP)
Этот показатель измеряет, как быстро пользователь получает самый тяжелый элемент контента, отрисованный на странице.
Давайте посмотрим, как мы можем улучшить этот показатель.
Оптимизируйте серверные операции
- Проверьте, насколько «быстрый» ваш хостинг-провайдер.
- Оптимизируйте запросы к базе данных.
- Используйте CDN для вашего сайта.
Настройте кэширование
Настройте кэширование статических ресурсов для уменьшения дорогостоящих серверных вычислений. Проанализируйте кэширование элементов, которые редко изменяются: изображения, PDF-документы, возможно, CSS- и JS-файлы.
Заранее настройте подключение к сторонним ресурсам
Уделите этому пункту особое внимание, так как он важен как для LCP, так и для FID.
Запросы сервера к сторонним ресурсам также могут повлиять на LCP, особенно если они нужны для отображения важного содержимого на странице.
Используйте rel="preconnect"
, чтобы сообщить браузеру, что ваша страница хочет установить соединение как можно скорее:
<link rel="preconnect" href="https://example.com" />
Вы также можете использовать dns-prefetch
для более быстрого поиска DNS:
<link rel="dns-prefetch" href="https://example.com" />
Несмотря на то, что оба метода работают по-разному, рассмотрите dns-prefetch как альтернативу для браузеров, которые не поддерживают предварительное подключение:
<head> … <link rel="preconnect" href="https://example.com" /> <link rel="dns-prefetch" href="https://example.com" /> </head>
Оптимизируйте CSS и JavaScript, которые блокируют поток
Уделите данному пункту особое внимание, так как он важен как для LCP, так и для FID.
Скрипты и стили блокируют рендеринг и ухудшают показатель LCP. Отложите любой некритический JavaScript и CSS, чтобы ускорить загрузку основного содержимого вашей веб-страницы.
Итак:
- Минимизируйте размер CSS и JS. Для облегчения чтения файлы CSS и JS могут содержать интервалы, отступы или комментарии. Все эти символы не нужны браузеру, и их минимизация гарантирует, что они будут удалены. Сделать это можно с помощью сборщиков модулей или инструментов сборки Webpack, Gulp или Rollup.
- Отложите загрузку некритического CSS. Используйте предварительную загрузку важных файлов стилей:
<link rel="preload" as="style" href="styles.css">
- Используйте медиа-запросы, чтобы сократить время вывода страницы на экран:
<link href="styles.css" rel="stylesheet" media="(min-width: 1920px)">
Pagespeed Insights часто указывает на неиспользуемые стили на странице, поэтому атрибут media может помочь в улучшении LCP.
- Заинлайньте критический CSS:
Помеcтите в тег <style>
критически важный CSS, необходимый при отрисовке верхней части страницы.
- Удалите неиспользуемый CSS и JS или переместите в отдельные файлы, если на разных страницах используется разный код. Используйте вкладку Coverage в Chrome DevTools для отладки:
Заранее загрузите ключевое изображение
Cамым важным и самым большим элементом для измерения LCP являются hero image в верхней части страницы. Для улучшения метрики настройте предзагрузку этих изображений:
<link rel="preload" as="image" href="image.jpg">
Важно! Предзагрузкой нужно пользоваться аккуратно. Пропускная способность соединения на первом этапе загрузки страницы невелика и предзагрузка нескольких картинок может повлиять на загрузку других важных ресурсов.
Убедитесь, что ресурсы расположены в правильном порядке, чтобы не привести к ухудшению других метрик, когда другие ресурсы тоже считаются важными (критический CSS, JS, шрифты). Подробнее о цене предзагрузки можно узнать тут.
В качестве примера предлагаю посмотреть на «карусель» баннеров в верхней части страницы. Настройка предварительной загрузки всех изображений внутри нее может негативно сказаться на LCP — вместо этого настройте предзагрузку первого изображения, остальные загружайте «лениво» (о чем поговорим ниже).
Используйте отзывчивые изображения с предварительной загрузкой
Используйте отзывчивые изображения с атрибутом srcset
и их предварительную загрузку. Познакомьтесь с возможностью предварительной загрузки адаптивных изображений. Благодаря атрибутам imagesrcset
и imagesizes
, добавленных в <link>
, вы можете предзагрузить адаптивные картинки:
<link rel="preload" as="image" href="your-image.jpg" imagesrcset="your-image_575px.jpg 575w, your-image_991px.jpg 991w, your-image_1920px.jpg 1920w" imagesizes="50vw">
В разметке же код должен выглядеть примерно так:
<img src="your-image.jpg" srcset=" your-image_575px.jpg 575w, your-image_991px.jpg 991w, your-image_1920px.jpg 1920w" sizes="50vw" loading="lazy" decoding="async" alt="">
Используйте эффективные современные форматы изображений
Размер изображений относительно нового формата WebP обычно на 25–35% меньше аналогов в формате JPEG и PNG. Это уменьшает влияние изображений на LCP и положительно сказывается на показателях загрузки. Поддержка этого формата уже довольно высока.
Избегайте изображений в высоком разрешении
Чаще всего желание предоставить пользователю изображения в лучшем разрешении только вредит. Как упоминалось в предыдущей статье, LCP сильно зависит от состояния сети и вычислительной мощности используемых устройств и высока вероятность, что пользователи сайта будут использовать устройства с меньшей мощностью, чем вы думаете. Именно поэтому, если возможно, старайтесь не использовать изображения в высоком разрешении, а также не забывайте их сжимать.
Используйте ленивую загрузку
Используйте ленивую загрузку для изображений вне зоны видимости.
Используя атрибут loading в <img>
, мы можем контролировать поведение загрузки изображения.
loading="lazy"
— отложенная загрузка изображений до тех пор, пока они не достигнут видимой области просмотра.
loading="eager"
— загружает изображения сразу, независимо от их видимости в области просмотра. Eager — значение по умолчанию, поэтому его не нужно явно добавлять (просто используйте <img>
для обычной загрузки).
Поддержка этого атрибута все еще находится в переходном состоянии.
В связи с этим для отложенной загрузки изображений мы используем JavaScript, чтобы проверить, находятся ли они в области просмотра. Современные браузеры предлагают проверить видимость элементов с помощью Intersection Observer API.
Сжимайте изображения
Для оптимизации форматов JPG и PNG попробуйте такие сервисы:
- ImageOptim — бесплатный оптимизатор изображений;
- Сompressor.io —уменьшает вес картинок до 90% (форматы JPEG, PNG, SVG, GIF и WEBP);
- TinyPNG — сжимает PNG- и JPEG-файлы;
- Squoosh — онлайн-конвертер изображений, работает с многими форматами, в том числе OptiPNG, MozJPG, WebP, PNG, JPG;
- для сжатия формата SVG — пользуйтесь решением Google-разработчика Джейка Арчибальда.
Предзагружайте шрифты
Иногда бывает, что самым крупным элементом страницы может быть элемент текста, который блокирует поток. Часто браузеры не отображают текст, написанный пользовательским шрифтом, пока файл шрифта не будет загружен.
Настройте их предварительную загрузку, чтобы процесс рендеринга текста прошел быстрее:
<link rel="preload" href="Circe-Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
Кроме того, в нашей доступности есть свойство CSS font-display
, которое можно использовать, чтобы указать браузеру отображать текст другим шрифтом (из цепочки font-family
) во время загрузки файла шрифта.
@font-face { font-family: 'Circe-Bold'; src: local('Circe-Bold'), url('Circe-Bold.woff2'); font-display: swap; }
Если включен font-display: swap
, текст отобразится на странице сразу после загрузки кода CSS.
Используйте современные форматы шрифтов
Используйте форматы woff и woff2.
Woff2 использует собственные алгоритмы предварительной обработки и сжатия, чтобы уменьшить размер файла примерно на 30% по сравнению с другими форматами.
First Input Delay (FID)
Этот показатель измеряет время, через которое пользователь может взаимодействовать со страницей. Давайте узнаем, как мы можем его улучшить.
Уменьшите влияние сторонних ресурсов
Убедитесь, что загрузка сторонних ресурсов несет реальную ценность для вашего сайта.
Как пример приведу один из самых используемых сторонних ресурсов — библиотеку jQuery. Она была отличным решением, когда не было общепринятого способа обращаться к элементам DOM с помощью CSS-селектора, не было стандартного способа добавить анимацию к стилю элемента, а интерфейс XMLHttpRequest, предложенный Internet Explorer, как и многие API, был плохо совместим с браузерами. Сейчас же нативные CSS и JS позволяют реализовать подавляющее число задач, поэтому рассмотрите вариант отказа от jQuery.
В тех случаях, когда на сайте необходимо использовать карусель изображений, для чего многие зачастую выбирали OwlCarousel или Slick, которые требуют jQuery, сейчас мы выбираем нативные решения, например, Swiper или Glider.js, которые мало весят и свободны от зависимостей. Для AJAX-запросов отдавайте предпочтение уже давно себя зарекомендовавшему Axios или же нативному Fetch.
И все же, если сторонние ресурсы важны для вашего сайта, попробуйте оптимизировать процесс их загрузки:
- Используйте атрибуты
async
илиdefer
для тега<script>
:
<script async src="script.js"> <script defer src="script.js">
Используйте async
, если важно, чтобы скрипт запустился раньше в процессе загрузки.
Используйте defer
для менее важных ресурсов (например, видеоплеер в нижней части страницы).
- Настройте подключение к этим ресурсам заблаговременно.
Вы можете сэкономить 100–500 миллисекунд, установив ранние подключения к важным сторонним источникам. Тут вам помогут два типа подключения тега <link>
: preconnect
и dns-prefetch
.
<link rel = "preconnect" href="https://cdn.example.com">
сообщает браузеру, что ваша страница намеревается установить соединение с другим источником и что вы хотите, чтобы процесс начался как можно скорее. Когда делается запрос ресурса из предварительно подключенного источника, загрузка начнется немедленно.
<link rel = "dns-prefetch">
обрабатывает небольшое подмножество того, что обрабатывает <link rel ="preconnect">
. Он включает в себя поиск DNS и подтверждение TCP, а для безопасных источников — согласование TLS.
Preconnect лучше всего использовать только для наиболее важных соединений. Для менее важных сторонних доменов используйте <link rel = dns-prefetch>
.
- Настройте ленивую загрузку данных ресурсов.
Встроенные сторонние ресурсы могут быть большим фактором снижения скорости страницы, если они спроектированы. Если они некритичны или находятся в нижней части страницы (если пользователям нужно прокручивать их для их просмотра), отложенная загрузка — хороший способ улучшить скорость страницы и отрисовку. Таким образом пользователи быстрее получат контент главной страницы.
Один из самых эффективных подходов — отложенная загрузка стороннего контента после загрузки главной страницы. Альтернативный подход — загружать сторонний контент только тогда, когда пользователь прокручивает страницу вниз до этого раздела страницы.
Используйте Intersection Observer — API браузера, который эффективно определяет, когда элемент попадает или пропадает из области просмотра браузера, и его можно использовать для реализации этого метода.
Уменьшите время выполнения JavaScript
Этот показатель идентичен шагам в разделе LCP. Еще раз отмечу их:
- минимизируйте и сжимайте JavaScript;
- удалите неиспользуемый JavaScript;
- отложите выполнение некритического JavaScript.
Минимизируйте работу в основном потоке
Уменьшите количество и размер запрашиваемых файлов.
Немного слов о «количестве ресурсов». Используйте вкладку «Задайте правила эффективного использования кэша для статических объектов» в Pagespeed Insight или вкладке Network в Chrome DevTools, чтобы посмотреть все ресурсы, которые загружены на странице:
Вкратце отмечу, что мы делаем, чтобы уменьшить количество ресурсов:
- Объединяем и минимизируем JavaScript.
- Объединяем и минимизируем CSS.
- Минимизируем использование свойства
background-image
в файлах стилей и инлайним графические элементы. - Уменьшаем влияние сторонних ресурсов.
- Оптимизируем длительно-выполняющиеся скрипты.
Используйте вкладку Performance в Chrome DevTools для поиска и отладки длительных операций. Определите, какие процессы являются наиболее затратными и по возможности оптимизируйте их.
Обратите внимание на процессы, которые отмечены как Long task и по возможности оптимизируйте их.
Еще одним способом поиска проблем является новая функция Pagespeed Insights — View treemap, которая позволяет увидеть, что находится в вашем JavaScript, найти зависимости и процент использования в коде.
- Загружайте Javascript асинхронно.
- Используйте методы прогрессивного улучшения, чтобы пользовательский интерфейс можно было использовать до запуска JavaScript.
- Ограничьте объем и сложности вычисления стилей.
- Не используйте большие сложные макеты и избегайте их подтормаживания.
Cumulative Layout Shift
Этот показатель предназначен для измерения визуальной стабильности страницы и отслеживает, насколько контент сдвигается, когда отрисовываются новые элементы.
Давайте поймем, как можно улучшить этот показатель.
Резервируйте места для изображений, видео и iframe-элементов
Зарезервировать места для изображений, видео и iframe-элементов можно, указав размеры.
Чтобы уменьшить сдвиг разметки, вызванный загрузкой ресурсов без заданных размеров, задайте картинкам и видео атрибуты width и height. Это помогает браузеру выделить достаточное место на странице, пока элементы грузятся:
<img src="image.jpg" alt="..." width="500" height="500">
Если ваше изображение должно быть отзывчивым, задайте ему в стилях свойство width со значением 100%, а height со значением auto. Тем самым мы может удовлетворить требования браузера и контролировать размеры изображения на медиа-запросах:
img { width: 100%; height: auto; }
Чтобы больше разобраться в вопросе, рекомендую прочитать статью Setting height and width on images is important again.
Используйте aspect-ratio
Если возможно, используйте CSS-свойство aspect-ratio, которое рассчитывается путем соотношения сторон, что в результате зарезервирует место для элемента. Поддержка свойства — в переходном состоянии, но сообщество возлагает на него большие надежды.
Настройте предварительную загрузку шрифтов
Настройте предварительную загрузку шрифтов и используйте CSS-свойство font-display: swap
, что в итоге предотвратит смещения текста в макете.
Избегайте динамической вставки элементов
Постарайтесь избегать динамической вставки элементов, в особенности в верхней части страницы, чтобы не повлиять на процесс взаимодействия пользователя со страницей.
Мы часто используем свое решение для генерации интерактивных компонентов: попапов, дропдаунов, селектов, табов, аккордеонов, других различных виджетов. В процессе инициализации многие из них используют динамическую вставку разметки. Решение проблемы сдвига контента в этом случае решается очевидным способом — указанием атрибутов width и height:
Избегайте раздельных анимаций
Избегайте использования свойств box-shadow
и filter
, которые браузер должен пересчитывать каждый раз, когда прорисовывает элемент. Анимации, необъединенные в общий композитный слой рендеринга, могут дергаться на слабых устройствах, если исполнение сложных JavaScript-задач занимает главный поток. Такие анимации могут вызывать и сдвиги раскладки.
Если Chrome обнаруживает, что анимация не может быть выделена в отдельный слой, он сообщает об этом в DevTools. Это позволяет составить список всех элементов, для которых анимация не была композитной, и выяснить причину. Вы можете найти эту информацию в отчете Avoid non-composited animations.
Вывод
Надеюсь, моя статья поможет вам улучшить ключевые показатели нового критерия ранжирования Google Core Web Vitals и быть готовым к изменениям, которые грядут в вебе. Вопрос улучшения веб-производительности вызвал большой ажиотаж в сообществах и, конечно же, преследует благую цель.
Команда Chrome постоянно занимается доработкой и исправлением этих критериев и несмотря на то, что в любой момент возможны breaking changes, основа критериев скорее всего останется нетронутой, поэтому показателями веб-производительности лучше всего заняться прямо сейчас.
Этот материал – не редакционный, это – личное мнение его автора. Редакция может не разделять это мнение.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: