Отладка производительности в полевых условиях

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

Google предоставляет две категории инструментов для измерения и отладки производительности:

  • Лабораторные инструменты: такие инструменты, как Lighthouse, где ваша страница загружается в смоделированную среду, которая может имитировать различные условия (например, медленную сеть и низкопроизводительное мобильное устройство).
  • Полевые инструменты: такие инструменты, как отчет об опыте пользователей Chrome (CrUX), который основан на совокупных данных реальных пользователей Chrome. (Обратите внимание, что данные полей, предоставляемые такими инструментами, как PageSpeed ​​Insights и Search Console, получены из данных CrUX.)

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

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

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

В связи с этим возникает важный вопрос: как можно получить отладочную информацию для Core Web Vitals или других показателей производительности от реальных пользователей на местах?

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

API для атрибуции и отладки

Совокупное изменение макета (CLS)

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

Рассмотрим следующий отчет PageSpeed ​​Insights:

Отчет PageSpeed ​​Insights с различными значениями CLS
PageSpeed ​​Insights показывает как полевые, так и лабораторные данные, если они доступны, и они могут отличаться.

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

Но даже если вы понимаете, что взаимодействие с пользователем влияет на данные полей, вам все равно необходимо знать, какие элементы на странице смещаются, чтобы получить оценку 0,28 в 75-м процентиле. Интерфейс LayoutShiftAttribution делает это возможным.

Получить атрибуцию изменения макета

Интерфейс LayoutShiftAttribution отображается в каждой записи layout-shift , которую создает API Layout Instability .

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

Вот пример кода, который регистрирует каждое изменение макета, а также элементы, которые сместились:

new PerformanceObserver((list) => {
  for (const {value, startTime, sources} of list.getEntries()) {
    // Log the shift amount and other entry info.
    console.log('Layout shift:', {value, startTime});
    if (sources) {
      for (const {node, curRect, prevRect} of sources) {
        // Log the elements that shifted.
        console.log('  Shift source:', node, {curRect, prevRect});
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});

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

Целью не является выявление и исправление каждого отдельного изменения макета, которое происходит у каждого пользователя; Цель состоит в том, чтобы определить изменения, которые затрагивают наибольшее количество пользователей и, таким образом, вносят наибольший вклад в CLS вашей страницы на 75-м процентиле.

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

Следующий код берет список записей layout-shift , которые внесли свой вклад в CLS, и возвращает самый большой исходный элемент из самого большого сдвига:

function getCLSDebugTarget(entries) {
  const largestEntry = entries.reduce((a, b) => {
    return a && a.value > b.value ? a : b;
  });
  if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
    const largestSource = largestEntry.sources.reduce((a, b) => {
      return a.node && a.previousRect.width * a.previousRect.height >
          b.previousRect.width * b.previousRect.height ? a : b;
    });
    if (largestSource) {
      return largestSource.node;
    }
  }
}

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

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

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

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

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

Самая большая содержательная краска (LCP)

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

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

Это может произойти по нескольким причинам:

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

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

Определите элемент-кандидат LCP

Чтобы определить элемент-кандидат LCP в JavaScript, вы можете использовать API Largest Contentful Paint — тот же API, который вы используете для определения значения времени LCP.

Наблюдая за записями largest-contentful-paint , вы можете определить текущий элемент-кандидат LCP, просматривая свойство element последней записи:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];

  console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});

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

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

Взаимодействие со следующей отрисовкой (INP)

Наиболее важной информацией, которую необходимо получить в полевых условиях для INP, являются:

  1. С каким элементом взаимодействовал
  2. Почему это был тип взаимодействия
  3. Когда произошло это взаимодействие

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

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

Следующий код регистрирует целевой элемент и время записи INP.

function logINPDebugInfo(inpEntry) {
  console.log('INP target element:', inpEntry.target);
  console.log('INP interaction type:', inpEntry.name);
  console.log('INP time:', inpEntry.startTime);
}

Обратите внимание, что этот код не показывает, как определить, какая запись event является записью INP, поскольку эта логика более сложна. Однако в следующем разделе объясняется, как получить эту информацию с помощью библиотеки JavaScript web-vitals .

Использование с библиотекой JavaScript web-vitals

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

Начиная с версии 3, библиотека JavaScript web-vitals включает в себя сборку атрибуции , которая отображает всю эту информацию, а также несколько дополнительных сигналов .

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

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      break;
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Этот код специфичен для Google Analytics, но общая идея должна быть применима и к другим инструментам аналитики.

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

Например, для отладки INP вам может потребоваться собрать элемент, с которым взаимодействует, тип взаимодействия, время, loadState, фазы взаимодействия и многое другое (например, данные длинного кадра анимации ).

Сборка атрибуции web-vitals предоставляет дополнительную информацию об атрибуции, как показано в следующем примере для INP:

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      eventParams.debug_type = attribution.interactionType;
      eventParams.debug_time = attribution.interactionTime;
      eventParams.debug_load_state = attribution.loadState;
      eventParams.debug_interaction_delay = Math.round(attribution.inputDelay);
      eventParams.debug_processing_duration = Math.round(attribution.processingDuration);
      eventParams.debug_presentation_delay =  Math.round(attribution.presentationDelay);
      break;

    // Additional metric logic...
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Полный список предоставляемых сигналов отладки см. в документации по атрибуции веб-виталов .

Составляйте отчеты и визуализируйте данные

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

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

Для GA4 см. специальную статью о том , как запрашивать и визуализировать данные с помощью BigQuery .

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

Надеемся, что этот пост помог обрисовать конкретные способы использования существующих API-интерфейсов производительности и библиотеки web-vitals для получения отладочной информации, которая поможет диагностировать производительность на основе посещений реальных пользователей на местах. Хотя это руководство сосредоточено на основных веб-показателях, эти концепции также применимы к отладке любых показателей производительности, которые можно измерить с помощью JavaScript.

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

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

Наконец, если вы чувствуете, что у вас есть пробелы в отладке этих показателей из-за отсутствия функций или информации в самих API, отправьте свой отзыв по адресу web-vitals-feedback@googlegroups.com .

,

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

Google предоставляет две категории инструментов для измерения и отладки производительности:

  • Лабораторные инструменты: такие инструменты, как Lighthouse, где ваша страница загружается в смоделированную среду, которая может имитировать различные условия (например, медленную сеть и низкопроизводительное мобильное устройство).
  • Полевые инструменты: такие инструменты, как отчет об опыте пользователей Chrome (CrUX), который основан на совокупных данных реальных пользователей Chrome. (Обратите внимание, что данные полей, предоставляемые такими инструментами, как PageSpeed ​​Insights и Search Console, получены из данных CrUX.)

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

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

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

В связи с этим возникает важный вопрос: как можно получить отладочную информацию для Core Web Vitals или других показателей производительности от реальных пользователей на местах?

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

API для атрибуции и отладки

Совокупное изменение макета (CLS)

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

Рассмотрим следующий отчет PageSpeed ​​Insights:

Отчет PageSpeed ​​Insights с различными значениями CLS
PageSpeed ​​Insights показывает как полевые, так и лабораторные данные, если они доступны, и они могут отличаться.

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

Но даже если вы понимаете, что взаимодействие с пользователем влияет на данные полей, вам все равно необходимо знать, какие элементы на странице смещаются, чтобы получить оценку 0,28 в 75-м процентиле. Интерфейс LayoutShiftAttribution делает это возможным.

Получить атрибуцию изменения макета

Интерфейс LayoutShiftAttribution отображается в каждой записи layout-shift , которую создает API Layout Instability .

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

Вот пример кода, который регистрирует каждое изменение макета, а также элементы, которые сместились:

new PerformanceObserver((list) => {
  for (const {value, startTime, sources} of list.getEntries()) {
    // Log the shift amount and other entry info.
    console.log('Layout shift:', {value, startTime});
    if (sources) {
      for (const {node, curRect, prevRect} of sources) {
        // Log the elements that shifted.
        console.log('  Shift source:', node, {curRect, prevRect});
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});

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

Целью не является выявление и исправление каждого отдельного изменения макета, которое происходит у каждого пользователя; Цель состоит в том, чтобы определить изменения, которые затрагивают наибольшее количество пользователей и, таким образом, вносят наибольший вклад в CLS вашей страницы на 75-м процентиле.

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

Следующий код берет список записей layout-shift , которые внесли свой вклад в CLS, и возвращает самый большой исходный элемент из самого большого сдвига:

function getCLSDebugTarget(entries) {
  const largestEntry = entries.reduce((a, b) => {
    return a && a.value > b.value ? a : b;
  });
  if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
    const largestSource = largestEntry.sources.reduce((a, b) => {
      return a.node && a.previousRect.width * a.previousRect.height >
          b.previousRect.width * b.previousRect.height ? a : b;
    });
    if (largestSource) {
      return largestSource.node;
    }
  }
}

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

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

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

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

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

Самая большая содержательная краска (LCP)

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

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

Это может произойти по нескольким причинам:

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

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

Определите элемент-кандидат LCP

Чтобы определить элемент-кандидат LCP в JavaScript, вы можете использовать API Largest Contentful Paint — тот же API, который вы используете для определения значения времени LCP.

Наблюдая за записями largest-contentful-paint , вы можете определить текущий элемент-кандидат LCP, просматривая свойство element последней записи:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];

  console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});

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

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

Взаимодействие со следующей отрисовкой (INP)

Наиболее важной информацией, которую необходимо получить в полевых условиях для INP, являются:

  1. С каким элементом взаимодействовал
  2. Почему это был тип взаимодействия
  3. Когда произошло это взаимодействие

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

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

Следующий код регистрирует целевой элемент и время записи INP.

function logINPDebugInfo(inpEntry) {
  console.log('INP target element:', inpEntry.target);
  console.log('INP interaction type:', inpEntry.name);
  console.log('INP time:', inpEntry.startTime);
}

Обратите внимание: этот код не показывает, как определить, какая запись event является записью INP, поскольку эта логика более сложна. Однако в следующем разделе объясняется, как получить эту информацию с помощью библиотеки JavaScript web-vitals .

Использование с библиотекой JavaScript web-vitals

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

Начиная с версии 3, библиотека JavaScript web-vitals включает в себя сборку атрибуции , которая отображает всю эту информацию, а также несколько дополнительных сигналов .

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

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      break;
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Этот код специфичен для Google Analytics, но общая идея должна быть применима и к другим инструментам аналитики.

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

Например, для отладки INP вам может потребоваться собрать элемент, с которым взаимодействует, тип взаимодействия, время, loadState, фазы взаимодействия и многое другое (например, данные длинного кадра анимации ).

Сборка атрибуции web-vitals предоставляет дополнительную информацию об атрибуции, как показано в следующем примере для INP:

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      eventParams.debug_type = attribution.interactionType;
      eventParams.debug_time = attribution.interactionTime;
      eventParams.debug_load_state = attribution.loadState;
      eventParams.debug_interaction_delay = Math.round(attribution.inputDelay);
      eventParams.debug_processing_duration = Math.round(attribution.processingDuration);
      eventParams.debug_presentation_delay =  Math.round(attribution.presentationDelay);
      break;

    // Additional metric logic...
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Полный список предоставляемых сигналов отладки см. в документации по атрибуции веб-виталов .

Составляйте отчеты и визуализируйте данные

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

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

Для GA4 см. специальную статью о том , как запрашивать и визуализировать данные с помощью BigQuery .

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

Надеемся, что эта статья помогла обозначить конкретные способы использования существующих API-интерфейсов производительности и библиотеки web-vitals для получения отладочной информации, которая поможет диагностировать производительность на основе посещений реальных пользователей на местах. Хотя это руководство сосредоточено на основных веб-показателях, эти концепции также применимы к отладке любых показателей производительности, которые можно измерить с помощью JavaScript.

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

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

Наконец, если вы чувствуете, что у вас есть пробелы в отладке этих показателей из-за отсутствия функций или информации в самих API, отправьте свой отзыв по адресу web-vitals-feedback@googlegroups.com .

,

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

Google предоставляет две категории инструментов для измерения и отладки производительности:

  • Лабораторные инструменты: такие инструменты, как Lighthouse, где ваша страница загружается в смоделированную среду, которая может имитировать различные условия (например, медленную сеть и низкопроизводительное мобильное устройство).
  • Полевые инструменты: такие инструменты, как отчет об опыте пользователей Chrome (CrUX), который основан на совокупных данных реальных пользователей Chrome. (Обратите внимание, что данные полей, предоставляемые такими инструментами, как PageSpeed ​​Insights и Search Console, получены из данных CrUX.)

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

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

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

В связи с этим возникает важный вопрос: как можно получить отладочную информацию для Core Web Vitals или других показателей производительности от реальных пользователей на местах?

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

API для атрибуции и отладки

Совокупное изменение макета (CLS)

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

Рассмотрим следующий отчет PageSpeed ​​Insights:

Отчет PageSpeed ​​Insights с различными значениями CLS
PageSpeed ​​Insights показывает как полевые, так и лабораторные данные, если они доступны, и они могут отличаться.

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

Но даже если вы понимаете, что взаимодействие с пользователем влияет на данные полей, вам все равно необходимо знать, какие элементы на странице смещаются, чтобы получить оценку 0,28 в 75-м процентиле. Интерфейс LayoutShiftAttribution делает это возможным.

Получить атрибуцию изменения макета

Интерфейс LayoutShiftAttribution отображается в каждой записи layout-shift , которую создает API Layout Instability .

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

Вот пример кода, который регистрирует каждое изменение макета, а также элементы, которые сместились:

new PerformanceObserver((list) => {
  for (const {value, startTime, sources} of list.getEntries()) {
    // Log the shift amount and other entry info.
    console.log('Layout shift:', {value, startTime});
    if (sources) {
      for (const {node, curRect, prevRect} of sources) {
        // Log the elements that shifted.
        console.log('  Shift source:', node, {curRect, prevRect});
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});

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

Целью не является выявление и исправление каждого отдельного изменения макета, которое происходит у каждого пользователя; Цель состоит в том, чтобы определить изменения, которые затрагивают наибольшее количество пользователей и, таким образом, вносят наибольший вклад в CLS вашей страницы на 75-м процентиле.

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

Следующий код берет список записей layout-shift , которые внесли свой вклад в CLS, и возвращает самый большой исходный элемент из самого большого сдвига:

function getCLSDebugTarget(entries) {
  const largestEntry = entries.reduce((a, b) => {
    return a && a.value > b.value ? a : b;
  });
  if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
    const largestSource = largestEntry.sources.reduce((a, b) => {
      return a.node && a.previousRect.width * a.previousRect.height >
          b.previousRect.width * b.previousRect.height ? a : b;
    });
    if (largestSource) {
      return largestSource.node;
    }
  }
}

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

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

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

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

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

Самая большая содержательная краска (LCP)

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

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

Это может произойти по нескольким причинам:

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

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

Определите элемент-кандидат LCP

Чтобы определить элемент-кандидат LCP в JavaScript, вы можете использовать API Largest Contentful Paint — тот же API, который вы используете для определения значения времени LCP.

Наблюдая за записями largest-contentful-paint , вы можете определить текущий элемент-кандидат LCP, просматривая свойство element последней записи:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];

  console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});

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

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

Взаимодействие со следующей отрисовкой (INP)

Наиболее важной информацией, которую необходимо получить в полевых условиях для INP, являются:

  1. С каким элементом взаимодействовал
  2. Почему это был тип взаимодействия
  3. Когда это взаимодействие произошло

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

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

Следующий код регистрирует целевой элемент и время записи INP.

function logINPDebugInfo(inpEntry) {
  console.log('INP target element:', inpEntry.target);
  console.log('INP interaction type:', inpEntry.name);
  console.log('INP time:', inpEntry.startTime);
}

Обратите внимание, что этот код не показывает, как определить, какая запись event является записью INP, так как эта логика более вовлечена. Однако в следующем разделе объясняется, как получить эту информацию, используя библиотеку JavaScript Web-Vitals .

Использование с библиотекой JavaScript Web-Vitals

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

С момента версии 3 библиотека JavaScript Web-Vitals включает в себя сборку атрибуции , которая вызывает всю эту информацию, а также несколько дополнительных сигналов .

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

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      break;
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Этот код специфичен для Google Analytics, но общая идея должна также перевести в другие инструменты аналитики.

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

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

Сборка атрибуции web-vitals раскрывает дополнительную информацию о атрибуции, как показано в следующем примере для INP:

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      eventParams.debug_type = attribution.interactionType;
      eventParams.debug_time = attribution.interactionTime;
      eventParams.debug_load_state = attribution.loadState;
      eventParams.debug_interaction_delay = Math.round(attribution.inputDelay);
      eventParams.debug_processing_duration = Math.round(attribution.processingDuration);
      eventParams.debug_presentation_delay =  Math.round(attribution.presentationDelay);
      break;

    // Additional metric logic...
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Обратитесь к документации по атрибуции Web-Vitals для полного списка обнаженных сигналов отладки.

Сообщите и визуализируйте данные

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

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

Для GA4 см. Выделенную статью о том , как запросить и визуализировать данные, используя BigQuery .

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

Надеемся, что этот пост помог рассказать о конкретных способах использования существующих API производительности и библиотеки web-vitals , чтобы получить информацию отладки, чтобы помочь диагностировать производительность на основе реальных посещений пользователей в этой области. В то время как это руководство сосредоточено на основных веб -жизненных возможностях, концепции также применяются для отладки любой показатели производительности, которая измерима в JavaScript.

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

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

Наконец, если вы чувствуете, что есть пробелы в вашей способности отладки эти метрики из-за отсутствующих функций или информации в самих API, отправьте ваши отзывы на Web-Vitals-feedback@googlegroups.com .