Оптимизировать самую большую содержательную отрисовку

Пошаговое руководство о том, как разбить LCP и определить ключевые области для улучшения.

Опубликовано: 30 апреля 2020 г.

Самый большой контент (LCP) — это один из трех показателей Core Web Vitals , который показывает, насколько быстро загружается основной контент веб-страницы. В частности, LCP измеряет время с момента, когда пользователь начинает загрузку страницы, до момента отображения самого большого изображения или текстового блока в области просмотра.

Чтобы обеспечить хорошее взаимодействие с пользователем, сайты должны стремиться к тому, чтобы LCP составляло 2,5 секунды или меньше как минимум для 75% посещений страниц.

Хорошие значения LCP составляют 2,5 секунды или меньше, плохие значения превышают 4,0 секунды, а все, что находится между ними, требует улучшения.
Хорошее значение LCP составляет 2,5 секунды или меньше.

Ряд факторов может повлиять на то, насколько быстро браузер сможет загружать и отображать веб-страницу, и задержки в любом из них могут оказать существенное влияние на LCP.

Редко бывает, чтобы быстрое исправление одной части страницы привело к значительному улучшению LCP. Чтобы улучшить LCP, вам необходимо рассмотреть весь процесс загрузки и убедиться, что каждый его шаг оптимизирован.

Понимание вашей метрики LCP

Прежде чем оптимизировать LCP, разработчики должны попытаться понять, есть ли у них вообще проблемы с LCP, а также масштабы таких проблем.

LCP можно измерить с помощью ряда инструментов, но не все из них измеряют LCP одинаково. Чтобы понять LCP реальных пользователей, нам следует посмотреть на то, что испытывают реальные пользователи, а не на то, что показывает лабораторный инструмент, такой как Lighthouse , или локальное тестирование. Эти лабораторные инструменты могут предоставить обширную информацию для объяснения и помощи в улучшении LCP, но имейте в виду, что сами по себе лабораторные тесты могут не полностью отражать то, что испытывают ваши реальные пользователи.

Данные LCP, основанные на реальных пользователях, можно получить с помощью инструментов мониторинга реальных пользователей (RUM), установленных на сайте, или с помощью отчета об опыте пользователей Chrome (CrUX), который собирает анонимные данные от реальных пользователей Chrome для миллионов веб-сайтов.

Использование данных Chrome DevTools CrUX LCP

На панели «Производительность» Chrome DevTools отображается ваш локальный LCP рядом с CrUX LCP страницы или источника в представлении показателей в реальном времени .

Локальный и полевой LCP на панели производительности Chrome DevTools
Локальный и полевой LCP на панели производительности Chrome DevTools.

Наслаивая данные полей на панель «Производительность», вы можете оценить, есть ли на странице какие-либо проблемы с LCP реальных пользователей, и адаптировать параметры локальной среды для лучшего воспроизведения и отладки этих проблем.

Использование данных PageSpeed ​​Insights CrUX LCP

PageSpeed ​​Insights предоставляет доступ к данным CrUX в верхнем разделе с надписью « Узнайте, что испытывают ваши реальные пользователи» . Более подробные лабораторные данные доступны в нижнем разделе « Диагностика проблем с производительностью» . Если для вашего веб-сайта доступны данные CrUX, всегда сначала концентрируйтесь на реальных данных пользователя.

Данные CrUX, показанные в PageSpeed ​​Insights
Данные CrUX показаны в PageSpeed ​​Insights.

PageSpeed ​​Insights отображает до четырех различных данных CrUX:

  • Мобильные данные для этого URL
  • Данные рабочего стола для этого URL
  • Мобильные данные для всего Origin
  • Данные рабочего стола для всего Origin

Вы можете переключать их с помощью элементов управления в верхней и верхней правой части этого раздела. Если в URL-адресе недостаточно данных для отображения на уровне URL-адреса, но имеются данные об источнике, PageSpeed ​​Insights всегда отображает данные об источнике.

PageSpeed ​​Insight возвращается к данным на уровне источника, когда данные на уровне URL-адреса недоступны.
Если в PageSpeed ​​Insights нет данных на уровне URL-адреса, он показывает данные на уровне источника.

LCP для всего источника может сильно отличаться от LCP отдельной страницы в зависимости от того, как LCP загружается на этой странице по сравнению с другими страницами этого источника. На это также может влиять то, как посетители переходят на эти страницы. Домашние страницы, как правило, посещаются новыми пользователями, поэтому часто могут загружаться «холодно», без какого-либо кэшированного контента, и поэтому часто являются самыми медленными страницами на веб-сайте.

Просмотр четырех различных категорий данных CrUX поможет вам понять, является ли проблема LCP специфичной для этой страницы или является более общей проблемой для всего сайта. Аналогично, он может показать, какие типы устройств имеют проблемы с LCP.

Использование дополнительных метрик PageSpeed ​​Insights CrUX

Тем, кто хочет оптимизировать LCP, следует также использовать тайминги первой отрисовки содержимого (FCP) и времени до первого байта (TTFB) , которые являются хорошими диагностическими показателями, которые могут предоставить ценную информацию о LCP.

TTFB — это время, когда посетитель начинает переходить на страницу (например, нажимая на ссылку), пока не будут получены первые байты HTML-документа. Высокий TTFB может сделать достижение LCP за 2,5 секунды затруднительным или даже невозможным.

Высокий TTFB может быть вызван несколькими перенаправлениями серверов, посетителями, расположенными далеко от ближайшего сервера сайта, посетителями в плохих условиях сети или невозможностью использовать кэшированный контент из-за параметров запроса.

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

Большая разница между TTFB и FCP может указывать на то, что браузеру необходимо загрузить много ресурсов, блокирующих рендеринг. Это также может быть признаком того, что для отображения какого-либо значимого контента необходимо выполнить большую работу — классический признак сайта, который в значительной степени полагается на рендеринг на стороне клиента.

Большая разница между FCP и LCP указывает на то, что ресурс LCP либо не доступен сразу для браузера для определения приоритета (например, текст или изображения, которые управляются JavaScript, а не доступны в исходном HTML), либо что браузер завершает работу. другую работу, прежде чем он сможет отобразить содержимое LCP.

Использование данных PageSpeed ​​Insights Lighthouse

Раздел Lighthouse в PageSpeed ​​Insights предлагает некоторые рекомендации по улучшению LCP, но сначала вам следует проверить, в целом ли данный LCP соответствует реальным пользовательским данным, предоставленным CrUX. Если Lighthouse и CrUX не согласны друг с другом, то CrUX, вероятно, предоставит более точную картину вашего пользовательского опыта. Прежде чем действовать, убедитесь, что ваши данные CrUX относятся к вашей странице, а не к полному источнику.

Если и Lighthouse, и CrUX показывают значения LCP, которые нуждаются в улучшении, раздел Lighthouse может предоставить ценные рекомендации по способам улучшения LCP. Используйте фильтр LCP, чтобы отображать только аудиты, относящиеся к LCP, следующим образом:

Возможности и диагностика Lighthouse LCP
Маячная диагностика и предложения по улучшению ЛКП.

Помимо возможностей улучшения, существует диагностическая информация, которая может предоставить дополнительную информацию, помогающую диагностировать проблему. Диагностика элемента «Самый большой контентный рисунок» показывает полезную разбивку различных таймингов, составляющих LCP:

Фазы LCP в Lighthouse
Разбивка Маяком элементов ЛКП.

Далее мы углубимся в эти подразделы.

Поломка ЛКП

Оптимизация для LCP может оказаться более сложной задачей, если PageSpeed ​​Insights не дает ответа, как улучшить этот показатель. Сложные задачи обычно лучше разбить на более мелкие, более выполнимые задачи и решать каждую отдельно.

В этом разделе представлена ​​методология разделения LCP на наиболее важные части, а затем представлены конкретные рекомендации и лучшие практики по оптимизации каждой части.

Большинство загрузок страниц обычно включают в себя несколько сетевых запросов, но в целях выявления возможностей улучшения LCP следует начать с рассмотрения только двух:

  1. Исходный HTML-документ
  2. Ресурс LCP (если применимо)

Хотя другие запросы на странице могут влиять на LCP, эти два запроса, а именно время начала и окончания ресурса LCP, показывают, оптимизирована ли ваша страница для LCP.

Чтобы идентифицировать ресурс LCP, вы можете использовать инструменты разработчика (такие как обсуждавшийся ранее PageSpeed ​​Insights, Chrome DevTools или WebPageTest ) для определения элемента LCP . Отсюда вы можете сопоставить URL-адрес (опять же, если применимо), загруженный элементом, в сетевом водопаде всех ресурсов, загруженных страницей.

Например, следующая визуализация показывает эти ресурсы, выделенные на каскадной диаграмме сети при типичной загрузке страницы, где элементу LCP требуется запрос изображения для рендеринга.

Сетевой водопад с выделенными ресурсами HTML и LCP.
Водопадная диаграмма, показывающая время загрузки HTML-кода веб-страницы и ресурсы, необходимые LCP.

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

Время до первого байта (TTFB)
Время с момента, когда пользователь начинает загрузку страницы, до момента получения браузером первого байта ответа HTML-документа.
Задержка загрузки ресурса
Время между TTFB и моментом, когда браузер начинает загрузку ресурса LCP. Если для отображения элемента LCP не требуется загрузка ресурса (например, если элемент представляет собой текстовый узел, отображаемый с использованием системного шрифта), это время равно 0.
Длительность загрузки ресурса
Время, необходимое для загрузки самого ресурса LCP. Если элемент LCP не требует загрузки ресурса для рендеринга, это время равно 0.
Задержка рендеринга элемента
Время между завершением загрузки ресурса LCP и полной отрисовкой элемента LCP.

LCP каждой страницы состоит из этих четырех подкатегорий. Между ними нет разрыва или дублирования, и они составляют полное время LCP.

Разбивка LCP с указанием четырех подкатегорий
Та же каскадная диаграмма с четырьмя подкатегориями LCP, наложенными на временную шкалу.

Значение LCP каждой страницы может быть разбито на эти четыре части. Между ними нет пересечения или разрыва. В совокупности они составляют полное время LCP.

При оптимизации LCP полезно попытаться оптимизировать эти части по отдельности. Но также важно помнить, что вам необходимо оптимизировать их все. В некоторых случаях оптимизация, примененная к одной части, не улучшит LCP, а просто перенесет сэкономленное время на другую часть.

Например, в предыдущем сетевом водопаде, если вы уменьшили размер файла нашего изображения, сильнее сжав его или переключившись на более оптимальный формат (например, AVIF или WebP), это уменьшило бы продолжительность загрузки ресурса , но не привело бы к этому. на самом деле улучшите LCP, потому что время просто сместится к подчасти задержки рендеринга элемента :

Та же разбивка LCP, показанная ранее, где подкатегория продолжительности загрузки ресурсов сокращается, но общее время LCP остается прежним.
Сокращение продолжительности загрузки ресурса увеличивает задержку отрисовки элемента без уменьшения LCP.

Причина, по которой это происходит, заключается в том, что на этой странице элемент LCP скрыт до тех пор, пока код JavaScript не завершит загрузку, а затем все сразу раскрывается.

Этот пример помогает проиллюстрировать необходимость оптимизации всех этих частей для достижения наилучших результатов LCP.

Оптимальное время обработки детали

Чтобы оптимизировать каждую часть LCP, важно понимать, какова идеальная разбивка этих частей на хорошо оптимизированной странице.

Из четырех подразделов в названии двух есть слово «задержка». Это подсказка о том, что вы хотите, чтобы это время было как можно ближе к нулю. Две другие части связаны с сетевыми запросами, которые по своей природе требуют времени.

Подчасть LCP % от ЛКП
Время до первого байта ~40%
Задержка загрузки ресурса <10%
Длительность загрузки ресурса ~40%
Задержка рендеринга элемента <10%
ОБЩИЙ 100%

Обратите внимание, что эти временные разбивки являются рекомендациями, а не строгими правилами. Если время LCP на ваших страницах постоянно находится в пределах 2,5 секунд, то не имеет особого значения, каковы относительные пропорции. Но если вы тратите много лишнего времени на любой из частей «задержки», то будет очень сложно постоянно достигать цели в 2,5 секунды .

Хороший способ подумать о разбивке времени LCP:

  • Подавляющее большинство времени LCP должно быть потрачено на загрузку HTML-документа и исходного кода LCP.
  • В любой момент перед LCP, когда один из этих двух ресурсов не загружается, появляется возможность улучшения .

Как оптимизировать каждую часть

Теперь, когда вы понимаете, как каждая часть времени LCP должна распределяться на хорошо оптимизированной странице, вы можете приступить к оптимизации своих собственных страниц.

В следующих четырех разделах будут представлены рекомендации и лучшие практики по оптимизации каждой части. Они представлены по порядку, начиная с оптимизаций, которые могут оказать наибольшее влияние.

1. Устраните задержку загрузки ресурсов .

Цель этого шага — обеспечить, чтобы ресурс LCP начал загружаться как можно раньше. Хотя теоретически ресурс может начать загружаться сразу после TTFB, на практике всегда существует некоторая задержка, прежде чем браузеры начнут фактически загружать ресурсы.

Хорошее практическое правило заключается в том, что ваш ресурс LCP должен начинать загрузку одновременно с первым ресурсом, загруженным этой страницей. Или, другими словами, если ресурс LCP начинает загружаться позже, чем первый ресурс, то есть возможность улучшения.

Водопадная диаграмма сети, показывающая ресурс LCP, начинающийся после первого ресурса, и показывающая возможность улучшения.
На этой странице ресурс LCP начинает загружаться сразу после таблицы стилей, которая загружается первой. Здесь есть куда совершенствоваться.

Вообще говоря, есть два фактора, которые влияют на скорость загрузки ресурса LCP:

  • Когда ресурс обнаружен.
  • Какой приоритет отдан ресурсу.

Оптимизация при обнаружении ресурса

Чтобы гарантировать, что ваш ресурс LCP начнет загружаться как можно раньше, очень важно, чтобы ресурс был доступен для обнаружения в исходном ответе HTML-документа сканером предварительной загрузки браузера. Например, в следующих случаях браузер может обнаружить ресурс LCP путем сканирования ответа HTML-документа:

  • Элемент LCP является элементом <img> , и его атрибуты src или srcset присутствуют в исходной HTML-разметке.
  • Для элемента LCP требуется фоновое изображение CSS , но это изображение предварительно загружается с помощью <link rel="preload"> в разметке HTML (или с помощью заголовка Link ).
  • Элемент LCP — это текстовый узел, для отображения которого требуется веб-шрифт, и шрифт загружается с помощью <link rel="preload"> в разметке HTML (или с помощью заголовка Link ).

Вот несколько примеров, когда ресурс LCP не может быть обнаружен при сканировании ответа HTML-документа:

  • Элемент LCP — это <img> , который динамически добавляется на страницу с помощью JavaScript.
  • Элемент LCP лениво загружается с помощью библиотеки JavaScript, которая скрывает его атрибуты src или srcset (часто как data-src или data-srcset ).
  • Для элемента LCP требуется фоновое изображение CSS.

В каждом из этих случаев браузеру необходимо запустить сценарий или применить таблицу стилей (что обычно предполагает ожидание завершения сетевых запросов), прежде чем он сможет обнаружить ресурс LCP и начать его загрузку. Это никогда не бывает оптимальным.

Чтобы исключить ненужную задержку загрузки ресурса, ваш ресурс LCP должен быть доступен для обнаружения из источника HTML. В тех случаях, когда на ресурс ссылаются только из внешнего файла CSS или JavaScript, ресурс LCP должен быть предварительно загружен с высоким приоритетом выборки , например:

<!-- Load the stylesheet that will reference the LCP image. -->
<link rel="stylesheet" href="/path/to/styles.css">

<!-- Preload the LCP image with a high fetchpriority so it starts loading with the stylesheet. -->
<link rel="preload" fetchpriority="high" as="image" href="/path/to/hero-image.webp" type="image/webp">

Оптимизируйте приоритет, который дается ресурсу

Даже если ресурс LCP можно обнаружить по разметке HTML, он все равно может не начать загрузку уже с первого ресурса. Это может произойти, если эвристика приоритетов сканера предварительной загрузки браузера не распознает важность ресурса или определяет, что другие ресурсы более важны.

Например, вы можете задержать изображение LCP с помощью HTML, если установите loading="lazy" в элементе <img> . Использование отложенной загрузки означает, что ресурс не будет загружен до тех пор, пока макет не подтвердит, что изображение находится в области просмотра, и поэтому загрузка может начаться позже, чем в противном случае.

Даже без отложенной загрузки изображения изначально не загружаются браузерами с наивысшим приоритетом, поскольку они не являются ресурсами, блокирующими рендеринг. Вы можете указать браузеру, какие ресурсы наиболее важны, используя атрибут fetchpriority для ресурсов, которым может быть полезен более высокий приоритет:

<img fetchpriority="high" src="/path/to/hero-image.webp">

Рекомендуется установить fetchpriority="high" для элемента <img> , если вы считаете, что это, скорее всего, элемент LCP вашей страницы. Однако установка высокого приоритета для более чем одного или двух изображений делает настройку приоритета бесполезной для снижения LCP.

Вы также можете снизить приоритет изображений, которые могут находиться в начале ответа документа, но не видны из-за стиля, например изображений в слайдах карусели, которые не видны при запуске:

<img fetchpriority="low" src="/path/to/carousel-slide-3.webp">

Удаление приоритета определенных ресурсов может предоставить большую пропускную способность ресурсам, которые в ней нуждаются больше, но будьте осторожны. Всегда проверяйте приоритет ресурсов в DevTools и тестируйте изменения с помощью лабораторных и полевых инструментов.

После того как вы оптимизировали приоритет и время обнаружения ресурса LCP, ваш сетевой водопад должен выглядеть следующим образом (ресурс LCP запускается одновременно с первым ресурсом):

Водопадная диаграмма сети, показывающая, что ресурс LCP теперь запускается одновременно с первым ресурсом.
Ресурс LCP теперь начинает загружаться одновременно с таблицей стилей.

2. Устранить задержку рендеринга элемента

Цель этого шага — обеспечить возможность визуализации элемента LCP сразу после завершения загрузки его ресурса, независимо от того, когда это произойдет.

Основная причина, по которой элемент LCP не сможет отрисовываться сразу после завершения загрузки ресурса, заключается в том, что рендеринг заблокирован по какой-либо другой причине:

  • Отображение всей страницы заблокировано из-за таблиц стилей или синхронных скриптов в <head> , которые все еще загружаются.
  • Ресурс LCP завершил загрузку, но элемент LCP еще не добавлен в DOM (он ожидает загрузки кода JavaScript).
  • Элемент скрыт каким-то другим кодом, например библиотекой A/B-тестирования, которая все еще определяет, в каком эксперименте должен участвовать пользователь.
  • Основной поток блокируется из-за длинных задач , и работу рендеринга приходится ждать, пока эти длинные задачи завершатся.

В следующих разделах объясняется, как устранить наиболее распространенные причины ненужной задержки отрисовки элементов.

Уменьшите или встройте таблицы стилей, блокирующие рендеринг.

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

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

Чтобы это исправить, вы можете:

  • встроить таблицу стилей в HTML, чтобы избежать дополнительного сетевого запроса; или,
  • уменьшите размер таблицы стилей.

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

В большинстве случаев лучший способ гарантировать, что таблица стилей не блокирует отрисовку элемента LCP, — это уменьшить его размер, чтобы он был меньше ресурса LCP. Это должно гарантировать, что это не станет узким местом для большинства посещений.

Некоторые рекомендации по уменьшению размера таблицы стилей:

Отложенный или встроенный блокирующий рендеринг JavaScript

Почти никогда нет необходимости добавлять синхронные скрипты (скрипты без атрибутов async или defer ) в <head> ваших страниц, и это почти всегда будет иметь негативное влияние на производительность.

В тех случаях, когда код JavaScript необходимо запустить как можно раньше при загрузке страницы, лучше всего встроить его, чтобы рендеринг не задерживался в ожидании другого сетевого запроса. Однако, как и в случае с таблицами стилей, встроенные скрипты следует использовать только в том случае, если они очень маленькие.

Не
<head>
  <script src="/path/to/main.js"></script>
</head>
Делать
<head>
  <script>
    // Inline script contents directly in the HTML.
    // IMPORTANT: only do this for very small scripts.
  </script>
</head>

Используйте рендеринг на стороне сервера

Рендеринг на стороне сервера (SSR) — это процесс выполнения логики клиентского приложения на сервере и ответа на запросы документов HTML с полной разметкой HTML.

С точки зрения оптимизации LCP есть два основных преимущества SSR:

  • Ваши графические ресурсы можно будет обнаружить из источника HTML (как обсуждалось ранее в шаге 1 ).
  • Содержимому вашей страницы не потребуются дополнительные запросы JavaScript для завершения, прежде чем оно сможет отображаться.

Основным недостатком SSR является то, что он требует дополнительного времени обработки сервера, что может замедлить работу вашего TTFB. Однако этот компромисс обычно того стоит, поскольку время обработки сервера находится под вашим контролем, а возможности сети и устройств ваших пользователей — нет.

Подобный вариант SSR называется генерацией статического сайта (SSG) или предварительной отрисовкой . Это процесс создания HTML-страниц на этапе сборки, а не по требованию. Если предварительный рендеринг возможен в вашей архитектуре, это, как правило, лучший выбор с точки зрения производительности.

Разбивайте длинные задачи

Даже если вы последовали предыдущему совету и ваш код JavaScript не блокирует рендеринг и не отвечает за рендеринг ваших элементов, он все равно может задерживать LCP.

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

Сегодня все браузеры отображают изображения в основном потоке, а это означает, что все, что блокирует основной поток, также может привести к ненужной задержке рендеринга элемента .

3. Уменьшить продолжительность загрузки ресурсов

Цель этого шага — сократить время, затрачиваемое на передачу байт ресурса по сети на устройство пользователя. В целом, есть четыре способа сделать это:

  • Уменьшите размер ресурса.
  • Уменьшите расстояние, которое должен пройти ресурс.
  • Уменьшите конкуренцию за пропускную способность сети.
  • Полностью исключите время работы в сети.

Уменьшите размер ресурса

Ресурс LCP страницы (если он есть) будет либо изображением, либо веб-шрифтом. Следующие руководства подробно описывают, как уменьшить размер обоих:

Уменьшите расстояние, которое ресурс должен пройти.

Помимо уменьшения размера ресурса, вы также можете сократить время загрузки, расположив серверы как можно ближе географически к вашим пользователям. И лучший способ сделать это — использовать сеть доставки контента (CDN).

CDN изображений особенно полезны, поскольку они не только сокращают расстояние, которое ресурс должен преодолеть, но и в целом уменьшают размер ресурса, автоматически реализуя для вас все приведенные ранее рекомендации по уменьшению размера.

Уменьшите конкуренцию за пропускную способность сети

Даже если вы уменьшили размер ресурса и расстояние, которое он должен пройти, загрузка ресурса все равно может занять много времени, если вы одновременно загружаете множество других ресурсов. Эта проблема известна как сетевая конкуренция .

Если вы присвоили ресурсу LCP высокий fetchpriority и начали его загружать как можно скорее , браузер сделает все возможное, чтобы предотвратить конкуренцию с ним ресурсов с более низким приоритетом. Однако если вы загружаете много ресурсов с высоким fetchpriority или просто загружаете много ресурсов в целом, это может повлиять на скорость загрузки ресурса LCP.

Полностью исключите время работы в сети

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

Если ваш ресурс LCP представляет собой веб-шрифт, помимо уменьшения размера веб-шрифта вам также следует подумать о том, нужно ли блокировать рендеринг при загрузке ресурса веб-шрифта. Если вы установите значение font-display , отличное от auto или block , тогда текст всегда будет виден во время загрузки , и LCP не будет блокироваться при дополнительном сетевом запросе.

Наконец, если ваш ресурс LCP небольшой, возможно, имеет смысл встроить ресурсы в виде URL-адреса данных , что также устранит дополнительный сетевой запрос. Однако при использовании URL-адресов данных возникают оговорки , поскольку в этом случае ресурсы невозможно кэшировать, а в некоторых случаях это может привести к более длительным задержкам рендеринга из-за дополнительных затрат на декодирование .

4. Сократите время до первого байта

Цель этого шага — как можно быстрее доставить исходный HTML-код. Этот шаг указан последним, поскольку зачастую именно его разработчики имеют наименьший контроль. Однако это также один из самых важных шагов, поскольку он напрямую влияет на каждый следующий шаг. Ничего не может произойти во внешнем интерфейсе, пока серверная часть не доставит первый байт контента, поэтому все, что вы можете сделать для ускорения вашего TTFB, также улучшит все остальные показатели нагрузки.

Распространенной причиной медленного TTFB для быстрого сайта являются посетители, поступающие через несколько перенаправлений, например, из рекламных объявлений или сокращенных ссылок . Всегда минимизируйте количество перенаправлений, которые посетителю приходится ждать.

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

Конкретные рекомендации по оптимизации TTFB см. в руководстве по оптимизации TTFB .

Мониторинг разбивки LCP в JavaScript

Информация о времени для всех подчастей LCP, обсуждавшихся ранее, доступна вам в JavaScript через комбинацию следующих API производительности:

Преимущество вычисления этих значений времени в JavaScript заключается в том, что они позволяют отправлять их поставщику аналитики или регистрировать их в инструментах разработчика, чтобы помочь в отладке и оптимизации.

Например, на следующем снимке экрана используется метод performance.measure() из API пользовательского времени для добавления полос на дорожку «Тайминги» на панели «Производительность» Chrome DevTools.

Пользовательские временные показатели подкатегорий LCP, визуализированные в Chrome DevTools
На дорожке «Время» отображаются временные шкалы для подкатегорий LCP.

Визуализация на дорожке «Тайминги» особенно полезна, если рассматривать ее вместе с дорожками «Сеть» и «Основной поток» , поскольку вы можете сразу увидеть, что еще происходит на странице в эти промежутки времени.

Помимо визуализации частей LCP на временной дорожке, вы также можете использовать JavaScript для вычисления процента каждой части от общего времени LCP. С помощью этой информации вы можете определить, соответствуют ли ваши страницы рекомендуемому процентному соотношению, описанному ранее.

На этом снимке экрана показан пример, который записывает на консоль общее время каждой части LCP, а также ее процент от общего времени LCP.

Время подкатегории LCP, а также их процент от LCP, выведенные на консоль.
Тайминги и проценты подкатегорий LCP.

Обе эти визуализации были созданы с помощью следующего кода:

const LCP_SUB_PARTS = [
  'Time to first byte',
  'Resource load delay',
  'Resource load duration',
  'Element render delay',
];

new PerformanceObserver((list) => {
  const lcpEntry = list.getEntries().at(-1);
  const navEntry = performance.getEntriesByType('navigation')[0];
  const lcpResEntry = performance
    .getEntriesByType('resource')
    .filter((e) => e.name === lcpEntry.url)[0];

  // Ignore LCP entries that aren't images to reduce DevTools noise.
  // Comment this line out if you want to include text entries.
  if (!lcpEntry.url) return;

  // Compute the start and end times of each LCP sub-part.
  // WARNING! If your LCP resource is loaded cross-origin, make sure to add
  // the `Timing-Allow-Origin` (TAO) header to get the most accurate results.
  const ttfb = navEntry.responseStart;
  const lcpRequestStart = Math.max(
    ttfb,
    // Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
    lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0
  );
  const lcpResponseEnd = Math.max(
    lcpRequestStart,
    lcpResEntry ? lcpResEntry.responseEnd : 0
  );
  const lcpRenderTime = Math.max(
    lcpResponseEnd,
    // Use LCP startTime (the final LCP time) because there are sometimes
    // slight differences between loadTime/renderTime and startTime
    // due to rounding precision.
    lcpEntry ? lcpEntry.startTime : 0
  );

  // Clear previous measures before making new ones.
  // Note: due to a bug, this doesn't work in Chrome DevTools.
  LCP_SUB_PARTS.forEach((part) => performance.clearMeasures(part));

  // Create measures for each LCP sub-part for easier
  // visualization in the Chrome DevTools Performance panel.
  const lcpSubPartMeasures = [
    performance.measure(LCP_SUB_PARTS[0], {
      start: 0,
      end: ttfb,
    }),
    performance.measure(LCP_SUB_PARTS[1], {
      start: ttfb,
      end: lcpRequestStart,
    }),
    performance.measure(LCP_SUB_PARTS[2], {
      start: lcpRequestStart,
      end: lcpResponseEnd,
    }),
    performance.measure(LCP_SUB_PARTS[3], {
      start: lcpResponseEnd,
      end: lcpRenderTime,
    }),
  ];

  // Log helpful debug information to the console.
  console.log('LCP value: ', lcpRenderTime);
  console.log('LCP element: ', lcpEntry.element, lcpEntry.url);
  console.table(
    lcpSubPartMeasures.map((measure) => ({
      'LCP sub-part': measure.name,
      'Time (ms)': measure.duration,
      '% of LCP': `${
        Math.round((1000 * measure.duration) / lcpRenderTime) / 10
      }%`,
    }))
  );
}).observe({type: 'largest-contentful-paint', buffered: true});

Вы можете использовать этот код «как есть» для локальной отладки или изменить его для отправки этих данных поставщику аналитики, чтобы вы могли лучше понять, какова структура LCP на ваших страницах для реальных пользователей.

Краткое содержание

LCP является сложным процессом, и на его время может влиять ряд факторов. Но если учесть, что оптимизация LCP — это прежде всего оптимизация загрузки ресурса LCP, то это может существенно упростить дело.

На высоком уровне оптимизацию LCP можно свести к четырем этапам:

  1. Убедитесь, что ресурс LCP начинает загружаться как можно раньше.
  2. Убедитесь, что элемент LCP может отображаться, как только его ресурс завершит загрузку.
  3. Сократите время загрузки ресурса LCP как можно больше, не жертвуя качеством.
  4. Доставьте начальный HTML -документ как можно быстрее.

Если вы можете выполнить эти шаги на своих страницах, то вы должны чувствовать себя уверенно, что вы предоставляете оптимальный опыт загрузки своим пользователям, и вы должны увидеть это отраженное в ваших реальных баллах LCP.