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

Частично итоговый результат совпадает с показателями Core Web Vitals, но в отличие от него, представляет более широкий набор показателей.

В настоящий момент оценку производительности Lighthouse составляют шесть показателей, включая Core Web Vitals, а также некоторые другие:

  • First Contentful Paint (FCP);
  • Speed Index (SI);
  • Largest Contentful Paint (LCP);
  • Time to Interactive (TTI);
  • Total Blocking Time (TBT);
  • Cumulative Layout Shift (CLS).

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

Все это означает, что вы можете получить очень высокую оценку производительности Lighthouse, окрашенную в зеленый цвет, и думать, что ваш сайт в порядке, но при всем при этом не пройти порог Core Web Vitals.

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

Данные наблюдений

Перейдем к блоку «Данные наблюдений» и получим еще одну путаницу:

Данные наблюдений сайта

First Contentful Paint отображается в блоке вместе с другими тремя Core Web Vitals, несмотря на то, что не является их частью. FCP всегда являлся одним из ключевых критериев и, вероятно, таким и останется. К этому разделу мы еще вернемся.

Имитация нагрузки страницы

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

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

Имитация загрузки страницы

Как видите, сюда включены LCP и CLS, и поскольку они являются частью Core Web Vitals, у них синяя этикетка и они выделяются как особо важные.

Что влияет на общий балл?

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

Lighthouse также выполняет около 50 других проверок дополнительных возможностей и диагностики. По словам Google, они не влияют ни на оценку, ни на Core Web Vitals, но могут использоваться веб-разработчиками для повышения производительности сайта.

Они отображаются в PageSpeed ​​Insights ниже:

Дополнительные рекомендации

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

Диагностика покажет вам элемент LCP и сдвиги, которые повлияли на вашу оценку CLS, что является очень полезной информацией при оптимизации для Core Web Vitals.

Хотя в прошлом сторонники веб-производительности могли в значительной степени сосредоточиться на оценках и аудитах Lighthouse, в ближайшее время внимание будет направлено на три основные показателя Core Web Vital.

Просмотр Core Web Vitals вашего сайта

Самый простой способ быстро взглянуть на Core Web Vitals для отдельного URL-адреса — ввести URL-адрес в PageSpeed ​​Insights, как я описывал выше.

Но чтобы увидеть, как Google видит Core Web Vitals для всего вашего сайта, необходимо получить доступ к Google Search Console.

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

Отчет Core Web Vitals в Google Search Console дает вам сводную информацию о том, насколько ваш сайт соответствовал критериям Core Web Vitals за последние 90 дней:

Отчет Core Web Vitals

Чтобы пройти критерии Core Web Vitals, все ваши страницы должны быть отмечены зеленым цветом. Несмотря на то, что оранжевая линия — хороший индикатор того, что вы близки к удаче, на самом деле, для получения всех преимуществ учитывается только зеленая.

Изначально Google применяет рейтинг Core Web Vitals только к мобильным устройствам, но на самом деле реализация таких алгоритмов для десктопных устройств — вопрос времени, поэтому не игнорируйте их оптимизацию.

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

Нажмите на URL-адрес, чтобы запустить PageSpeed ​​Insights для быстрого аудита производительности определенного адреса страницы (включая отображение данных о Core Web Vitals для этой страницы).

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

Но после кропотливой работы, вы, возможно, будете разочарованы тем, что отчет Core Web Vitals не изменился, а PageSpeed ​​Insights упорно продолжает показывать URL и сайт в целом как неисправные.

Почему? Давайте разбираться.

Отчет о пользовательском опыте Chrome (CrUX)

Причина, по которой Web Vitals обновляется довольно медленно заключается в том, что данные формируются на основе последних 21-28 дней пользовательского опыта Chrome (CrUX) — именно столько времени достаточно для устранения разного рода отклонений и отображения более точной производительности вашего сайта.

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

Дополнительная информация о данных CrUX

CrUX — это инструмент Chrome. Пользователи iOS-устройств и других браузеров (десктопная версия Safari, Firefox, Opera, Edge) никаким образом не влияют на данные CrUX, а соответственно, и на показатели Core Web Vitals вашего сайта.

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

Используемая версия Chrome также будет иметь влияние на показатели, поскольку все критерии все еще находятся в стадии развития и изменений(в частности, CLS).

CrUX включает в себя все страницы, в том числе и те, которые обычно не отображаются в поиске Google (например с мета-тегом <meta name=”robots” content=”noindex”>). Теперь такие страницы, скорее всего, не будут включены в результаты поиска Google и не будут влиять на ранжирование, несмотря на то, что в CrUX вы все еще будете их наблюдать.

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

Теперь мы знаем, каким образом собираются и анализируются данные, но актуальным становится вопрос: как ускорить обновление наших изменений во время разработки? Ждать 21-28 дней, чтобы увидеть влияние данных CrUX — только для того, чтобы понять, что ваших исправлений было недостаточно?

Получение мгновенных результатов об изменениях в CRuX

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

Но в этой статье мы рассмотрим два других инструмента — расширение для браузера Chrome Web Vitals Chrome Extension и JavaScript-библиотеку для фронтенд-разработчиков web-vitals.

Расширение Web Vitals Chrome Extension

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

Расширение Web Vitals Chrome Extension — жмем «Установить»

Спустя пару секунд расширение будет установлено в браузере Chrome.

Отображается расширение в виде квадрата:

Отображение расширения соответствующим цветом

Он может быть трех цветов:

  • зеленый — хорошие показатели Core Web Vitals;
  • красный — плохие показатели Core Web Vitals;
  • серый — показатели недоступны.

Нажав на иконку расширения, получим более точные данные по конкретным метрикам:

Данные по метрикам

Это минималистичная (1 кБ) библиотека, которая создана для фронтенд-мониторинга. По моему мнению, это самый эффективный инструмент, потому что позволяет отследить показатели за короткие промежутки времени с очень высокой точностью.

Полное описание по установке и использованию, а также API данной библиотеки можно посмотреть тут.

Я же опишу ее главные функции. Итак, приступим!

Установка и загрузка библиотеки с помощью npm

npm install web-vitals

Существует две разные версии библиотеки web-vitals («стандартная» версия и версия base + polyfill). То, как вы загружаете библиотеку, зависит от того, какую версию вы хотите использовать.

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

«Стандартная» версия

Для загрузки импортируйте модули из пакета web-vitals в код своего приложения:

import {getLCP, getFID, getCLS} from 'web-vitals';
 
getCLS(console.log);
getFID(console.log);
getLCP(console.log);

«Базовая версия с полифиллом»

Загрузка версии base + polyfill — это двухэтапный процесс.

Сначала в коде вашего приложения импортируйте «базовую» сборку, вместо «стандартной». Для этого достаточно изменить путь на web-vitals/base:

import {getLCP, getFID, getCLS} from 'web-vitals/base';

Затем вставьте код из dist/polyfill.js, который находится в папке установленной библиотеки в <head> своих страниц. Этот шаг важен, поскольку «базовая» сборка не сработает, если код полифилла не будет добавлен.

<!DOCTYPE html>
<html>
  <head>
    <script>
      // Код из `dist/polyfill.js`
    </script>
  </head>
  <body>
    ...
  </body>
</html>

Установка и загрузка библиотеки с помощью CDN

Авторы рекомендуют устанавливать библиотеку через npm и интегрировать сборку в ваш код. Но если вы не используете npm, подключение web-vitals с помощью CDN все еще допускается.

Примеры ниже отображают загрузку web-vitals вне зависимости, нацелены ли вы на браузеры, построенные на кодовой базе Chromium (используя «стандартную версию») или не нацелены (используя «базовую версию с полифиллом»).

Загрузка «стандартной версии» (используя <script type=’module’></script>):

<script type="module">
  import {getCLS, getFID, getLCP} from 'https://unpkg.com/web-vitals?module';
 
  getCLS(console.log);
  getFID(console.log);
  getLCP(console.log);
</script>

Загрузка «стандартной версии» (используя тег <script></script>):

<script>
(function() {
  var script = document.createElement('script');
  script.src = 'https://unpkg.com/web-vitals';
  script.onload = function() {
    // Когда вы используете `web-vitals` используя классический вид тега script, 
// все публичные методы будут доступны в глобальном объекте `webVitals`
    webVitals.getCLS(console.log);
    webVitals.getFID(console.log);
    webVitals.getLCP(console.log);
  }
  document.head.appendChild(script);
}())
</script>

Загрузка «базовой версии с полифиллом» (используя тег <script></script>):

<!DOCTYPE html>
<html>
  <head>
    <script>
      // Вставьте код из `https://unpkg.com/web-vitals/dist/polyfill.js` тут.
    </script>
  </head>
  <body>
    ...
    <!-- Загрузите UMD версию “базовой сборки”. -->
    <script>
    (function() {
      var script = document.createElement('script');
      script.src = 'https://unpkg.com/web-vitals';
      script.onload = function() {
        // Когда вы используете `web-vitals` используя классический вид тега script, 
// все публичные методы будут доступны в глобальном объекте `webVitals`
        webVitals.getCLS(console.log);
        webVitals.getFID(console.log);
        webVitals.getLCP(console.log);
      }
      document.head.appendChild(script);
    }())
    </script>
  </body>
</html>

Каждая метрика Web Vitals представлена ​​в виде отдельной функции, которая принимает коллбэк onReport, который будет вызываться каждый раз, когда значение метрики доступно и готово к отправке.

В следующем примере измеряется каждая из метрик Core Web Vitals и как только значение для отчета получено — выводится в консоль.

Примеры ниже используют «стандартную» сборку, но они также будут работать с версией полифилла.

import {getCLS, getFID, getLCP} from 'web-vitals';
 
getCLS(console.log);
getFID(console.log);
getLCP(console.log);

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

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

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

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

Получение значения при каждом изменении

В большинстве случаев коллбэк «onReport» вам понадобится лишь тогда, когда значение метрики будет доступно. Но у вас есть возможность получать значение при каждом изменении (например, при каждом сдвиге макета), установив необязательный второй аргумент reportAllChanges в значение true.

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

import {getCLS} from 'web-vitals';
// Выводит в консоль значение CLS при каждом изменении.
getCLS(console.log, true);

Получение только дельты изменений

Некоторые инструменты аналитики позволяют обновлять значение метрики даже после того, как вы уже отправили ее сервер (перезаписывая ранее отправленное значение с тем же id).

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

Рассмотрим на примере, как использовать свойства id и delta:

import {getCLS, getFID, getLCP} from 'web-vitals';
function logDelta({name, id, delta}) {
  console.log(`Разница между текущим значением и последним сообщенным у ${name}, который соответствует ID ${id} равен ${delta}`);
}
getCLS(logDelta);
getFID(logDelta);
getLCP(logDelta);

Отправка результатов в конечную точку аналитики

В следующем примере измеряется каждая из метрик Core Web Vitals и отправляется по гипотетическому адресу аналитики, как только каждая из них будет готова к отправке.

Функция sendToAnalytics() использует метод navigator.sendBeacon() (если он доступен), в противном случае возвращается к fetch() API.

import {getCLS, getFID, getLCP} from 'web-vitals';
 
function sendToAnalytics(metric) {
  const body = JSON.stringify({[metric.name]: metric.value});
  // Используется `navigator.sendBeacon()` (если доступен), в противном случае `fetch()`.
  (navigator.sendBeacon && navigator.sendBeacon('/analytics', body)) ||
      fetch('/analytics', {body, method: 'POST', keepalive: true});
}
 
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getLCP(sendToAnalytics);

Отправка результатов в Google Analytics

В том случае, если вы установите уникальное значение параметра (в данном случае id метрики, как в примерах ниже) для каждого экземпляра метрики, которую вы отправляете в Google Analytics, вы можете создать отчет, используя Google Analytics Reporting API и любую библиотеку визуализации данных на ваш выбор.

Например, отчет Web Vitals Report  — бесплатный инструмент с открытым исходным кодом, который вы можете использовать для создания визуализаций данных Web Vitals, которые вы отправили в Google Analytics.

Отчет Web Vitals Report

Чтобы использовать Web Vitals Report (или создавать свои собственные пользовательские отчеты с помощью API), вам необходимо отправить свои данные в Google Analytics, следуя одному из примеров ниже:

Использование analytics.js:

import {getCLS, getFID, getLCP} from 'web-vitals';
 
function sendToGoogleAnalytics({name, delta, id}) {
  // Предполагает, что глобальная функция `ga()` существует, подробнее тут:
  // https://developers.google.com/analytics/devguides/collection/analyticsjs
  ga('send', 'event', {
    eventCategory: 'Web Vitals',
    eventAction: name,
    // Параметр`id` будет уникальным для текущей загрузки страницы. 
    // При отправке нескольких значений с одной и той же страницы(например CLS), 
    // Google Analytics может вычислить результат путем группировки параметров ID 
    //(важно: требуется ключ `eventLabel`, который будет специальным параметром)
    eventLabel: id,
    // Показатели Google Analytics должны быть целыми числами.
    // Для CLS значение сначала умножается на 1000 для лучшей точности
    // (важно: при необходимости увеличьте множитель для еще большей точности).
    eventValue: Math.round(name === 'CLS' ? delta * 1000 : delta),
    // Используйте ключ nonInteraction, чтобы не повлиять на “показатель отказов”.
    nonInteraction: true,
    // Используйте `sendBeacon()` если ваш браузер поддерживает данный метод.
    transport: 'beacon'
   });
}
 
getCLS(sendToGoogleAnalytics);
getFID(sendToGoogleAnalytics);
getLCP(sendToGoogleAnalytics);

Использование gtag.js (Universal Analytics):

import {getCLS, getFID, getLCP} from 'web-vitals';
 
function sendToGoogleAnalytics({name, delta, id}) {
  // Предполагает, что глобальная функция `gtag()` существует, подробнее тут:
  // https://developers.google.com/analytics/devguides/collection/gtagjs
  gtag('event', name, {
    event_category: 'Web Vitals',
    // Параметр`id` будет уникальным для текущей загрузки страницы. 
    // При отправке нескольких значений с одной и той же страницы(например CLS), 
    // Google Analytics может вычислить результат путем группировки параметров ID 
    //(важно: требуется ключ `eventLabel`, который будет специальным параметром)
    event_label: id,
    // Показатели Google Analytics должны быть целыми числами.
    // Для CLS значение сначала умножается на 1000 для лучшей точности
    // (важно: при необходимости увеличьте множитель для еще большей точности).
    value: Math.round(name === 'CLS' ? delta * 1000 : delta),
    // Используйте ключ non_interaction, чтобы не повлиять на “показатель отказов”.
    non_interaction: true
  });
}
 
getCLS(sendToGoogleAnalytics);
getFID(sendToGoogleAnalytics);
getLCP(sendToGoogleAnalytics);

Использование gtag.js (Google Analytics 4)

Google Analytics 4 предоставляет новую модель событий, позволяющую настраивать параметры вместо фиксированных категорий, действий и меток. Он также поддерживает нецелочисленные значения, что упрощает измерение показателей Web Vitals по сравнению с предыдущими версиями.

import {getCLS, getFID, getLCP} from 'web-vitals';
 
function sendToGoogleAnalytics({name, delta, value, id}) {
  // Предполагает, что глобальная функция `gtag()` существует, подробнее тут:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, {
    // Встроенные параметры:
    value: delta, // Используйте `delta`, следовательно значение может суммироваться.
    // Кастомные параметры:
    metric_id: id, // Требуется для агрегирования событий.
    metric_value: value, // необязательно.
    metric_delta: delta, // необязательно.
  });
}
 
getCLS(sendToGoogleAnalytics);
getFID(sendToGoogleAnalytics);
getLCP(sendToGoogleAnalytics);

Отправка результатов в Google Tag Manager

Рекомендуемый способ измерения показателей Web Vitals с помощью Google Tag Manager — использование настраиваемого тега шаблона Core Web Vitals.

Полную инструкцию по установке и использованию Google Tag Manager читайте тут.

Короткое резюме

У Google большая власть в области веба. Компания не всегда действовала из лучших побуждений, но Core Web Vitals преследует благородную цель. Теперь у нас есть инструменты, которые измеряют показатели производительности страницы на основе реального опыта. Они помогут разработчикам сконцентрироваться на улучшениях, которые принесут наибольшую пользу пользователям.

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

JavaScript-библиотека web-vitals помогает разработчикам существенно повысить скорость и эффективность контроля веб-производительности.

Надеюсь, эта статья помогла вам лучше понять три важных критерия Core Web Vitals. Ну а в следующей я расскажу, что мы делаем, чтобы достичь наилучших показателей Core Web Vitals.