Экспериментируем с измерением мягкой навигации

С момента своего запуска инициатива Core Web Vitals стремилась измерить фактический пользовательский опыт веб-сайта, а не технические детали того, как веб-сайт создается или загружается. Три метрики Core Web Vitals были созданы как метрики, ориентированные на пользователя — это эволюция существующих технических показателей, таких как DOMContentLoaded или load , которая измеряла время, которое часто не было связано с тем, как пользователи воспринимают производительность страницы. По этой причине технология, использованная для создания сайта, не должна влиять на оценку, если сайт работает хорошо.

Реальность всегда немного сложнее идеала, и популярная архитектура одностраничных приложений никогда полностью не поддерживалась метриками Core Web Vitals . Вместо загрузки отдельных отдельных веб-страниц при навигации пользователя по сайту эти веб-приложения используют так называемую «мягкую навигацию», при которой содержимое страницы вместо этого изменяется с помощью JavaScript. В этих приложениях иллюзия традиционной архитектуры веб-страницы поддерживается за счет изменения URL-адреса и добавления предыдущих URL-адресов в историю браузера, чтобы кнопки «Назад» и «Вперед» работали так, как ожидает пользователь.

Многие фреймворки JavaScript используют эту модель, но каждый по-своему. Поскольку это выходит за рамки того, что браузер традиционно понимает под «страницей», измерить это всегда было сложно: где провести грань между взаимодействием на текущей странице и рассмотрением ее как новой страницы?

Команда Chrome уже некоторое время рассматривает эту задачу и стремится стандартизировать определение того, что такое «мягкая навигация», и то, как для этого можно измерить основные веб-показатели — аналогично тому, как это реализовано на веб-сайтах. в традиционной многостраничной архитектуре (MPA). Хотя это все еще находится на ранней стадии, команда теперь готова сделать то, что уже реализовано, более доступным для экспериментов на сайтах. Это позволит сайтам оставить отзыв о подходе, который применяется на данный момент.

Что такое программная навигация?

Мы пришли к следующему определению мягкой навигации :

  • Навигация инициируется действием пользователя.
  • Результатом навигации является видимое для пользователя изменение URL-адреса и изменение истории.
  • Навигация приводит к изменению DOM.

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

Как Chrome реализует мягкую навигацию?

Как только эвристика мягкой навигации будет включена (подробнее об этом в следующем разделе), Chrome изменит способ сообщения некоторых показателей производительности:

  • Событие soft-navigation PerformanceTiming будет генерироваться после обнаружения каждой программной навигации.
  • API производительности предоставит доступ к записи времени soft-navigation , созданной событием soft-navigation PerformanceTiming .
  • Метрики First Paint (FP) , First Contentful Paint (FCP) , Largest Contentful Paint (LCP) будут сброшены и повторно отправлены при следующем соответствующем их появлении. (Примечание: FP и FCP не реализованы.)
  • Атрибут navigationId будет добавлен к каждому времени производительности ( first-paint , first-contentful-paint , largest-contentful-paint , first-input-delay , event и layout-shift ), соответствующему навигационной записи, с которой было связано событие. чтобы можно было рассчитать совокупный сдвиг макета (CLS) и взаимодействие со следующей отрисовкой (INP) .

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

Каковы последствия включения программной навигации в Chrome?

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

  • Дополнительные события FP, FCP и LCP могут быть повторно отправлены для программной навигации. Отчет об опыте пользователей Chrome (CrUX) будет игнорировать эти дополнительные значения, но это может повлиять на мониторинг реальных пользователей (RUM) на вашем сайте. Если у вас есть какие-либо опасения, повлияет ли это на эти измерения, обратитесь к своему поставщику RUM. См. раздел об измерении основных веб-жизненных показателей для программной навигации .
  • Новый (и необязательный) атрибут navigationID в ваших записях производительности, возможно, придется учитывать в коде вашего приложения, использующего эти записи.
  • Только браузеры на базе Chromium будут поддерживать этот новый режим. Хотя многие из новых показателей доступны только в браузерах на базе Chromium, некоторые (FCP, LCP) доступны и в других браузерах, и не все, возможно, обновились до последней версии браузеров на базе Chromium. Имейте в виду, что некоторые пользователи могут не сообщать о показателях программной навигации.
  • Поскольку это новая экспериментальная функция, которая не включена по умолчанию, сайтам следует протестировать ее, чтобы убедиться в отсутствии других непредвиденных побочных эффектов.

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

Как включить программную навигацию в Chrome?

Мягкая навигация по умолчанию не включена в Chrome, но доступна для экспериментирования, если явно включить эту функцию.

Для разработчиков это можно включить, включив флаг функций экспериментальной веб-платформы в chrome://flags/#enable-experimental-web-platform-features или используя командную строку --enable-experimental-web-platform-features аргумент при запуске Chrome.

Как я могу измерить мягкую навигацию?

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

Сообщить о программной навигации

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

const observer = new PerformanceObserver(console.log);
observer.observe({ type: "soft-navigation", buffered: true });

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

Сообщите о показателях по соответствующему URL-адресу.

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

Атрибут navigationId соответствующего PerformanceEntry можно использовать для привязки события к правильному URL-адресу. Это можно посмотреть с помощью PerformanceEntry API :

const softNavEntry =
  performance.getEntriesByType('soft-navigation').filter(
    (entry) => entry.navigationId === navigationId
  )[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const pageUrl = navEntry?.name;

Этот pageUrl следует использовать для отчета о показателях по правильному URL-адресу, а не по текущему URL-адресу, который они могли использовать в прошлом.

startTime с программной навигацией

Время начала навигации можно получить аналогичным образом:

const softNavEntry =
  performance.getEntriesByType('soft-navigation').filter(
    (entry) => entry.navigationId === navigationId
  )[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const startTime = navEntry?.startTime;

startTime — это время начального взаимодействия (например, нажатия кнопки), которое инициировало программную навигацию.

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

Измерение основных веб-показателей с помощью программной навигации

Чтобы включить записи показателей программной навигации, вам необходимо включить includeSoftNavigationObservations: true в вызов observe вашего наблюдателя производительности.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('Layout Shift time:', entry);
  }
}).observe({type: 'layout-shift', buffered: true, includeSoftNavigationObservations: true});

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

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

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    const softNavEntry =
      performance.getEntriesByType('soft-navigation').filter(
        (navEntry) => navEntry.navigationId === entry.navigationId
      )[0];
    const hardNavEntry = performance.getEntriesByType('navigation')[0];
    const navEntry = softNavEntry || hardNavEntry;
    const startTime = navEntry?.startTime;
    console.log('LCP time:', entry.startTime - startTime);
  }
}).observe({type: 'largest-contentful-paint', buffered: true, includeSoftNavigationObservations: true});

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

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

Как следует относиться к контенту, который остается неизменным между навигациями?

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

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

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

Как измерить TTFB?

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

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

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

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

Как измерить старое и новое?

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

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

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

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

Самый простой способ учесть все нюансы — использовать JavaScript-библиотеку web-vitals , в которой имеется экспериментальная поддержка программной навигации в отдельной soft-navs branch (которая также доступна на npm и unpkg ). Это можно измерить следующим образом (заменив doTraditionalProcessing и doSoftNavProcessing по мере необходимости):

import {
  onTTFB,
  onFCP,
  onLCP,
  onCLS,
  onINP,
} from 'https://unpkg.com/web-vitals@soft-navs/dist/web-vitals.js?module';

onTTFB(doTraditionalProcessing);
onFCP(doTraditionalProcessing);
onLCP(doTraditionalProcessing);
onCLS(doTraditionalProcessing);
onINP(doTraditionalProcessing);

onTTFB(doSoftNavProcessing, {reportSoftNavs: true});
onFCP(doSoftNavProcessing, {reportSoftNavs: true});
onLCP(doSoftNavProcessing, {reportSoftNavs: true});
onCLS(doSoftNavProcessing, {reportSoftNavs: true});
onINP(doSoftNavProcessing, {reportSoftNavs: true});

Убедитесь, что метрики передаются по правильному URL-адресу , как отмечалось ранее .

Библиотека web-vitals сообщает следующие показатели для программной навигации:

Метрика Подробности
ТТФБ Сообщается как 0.
ФКП Сообщается только о первом FCP для страницы.
ЛКП Время следующей по величине отрисовки содержимого относительно времени начала программной навигации. Существующие краски, присутствующие в предыдущей навигации, не учитываются. Следовательно, LCP будет >= 0. Как обычно, об этом будет сообщено при взаимодействии или когда страница находится в фоновом режиме, поскольку только тогда LCP может быть завершен.
ЦЛС Самое большое окно смены времени навигации. Как обычно, это когда страница находится в фоновом режиме, и только тогда можно завершить CLS. Значение 0 сообщается, если сдвигов нет.
ИЯФ INP между периодами навигации. Как обычно, об этом будет сообщено при взаимодействии или когда страница окажется в фоновом режиме, и только тогда INP можно будет завершить. Значение 0 не сообщается, если нет взаимодействий.

Станут ли эти изменения частью показателей Core Web Vitals?

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

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

Как в Crux будет отображаться информация о программной навигации?

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

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

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

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

Обратная связь

Мы активно ищем отзывы об этом эксперименте в следующих местах:

Журнал изменений

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

Заключение

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

Благодарности

Миниатюрное изображение Джордана Мадрида на Unsplash