INP и SPA

Содержание

В общем и целом, как собирать INP понятно — подключаем npm пакет web-vitals, делаем импорт нужного метода, передаём в него колбэк для сохранения данных.

import { onINP } from 'web-vitals';

const sendToBackend = (data) => {
  // сохраняем данные на бэкенд
}

onINP(sendToBackend);

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

Проблема SPA

Если у вас SPA, и вы хотите при переходе на новую страницу без перезагрузки (soft навигация) начать собирать INP заново — тут начинаются сложности.

Сам недавно с таким столкнулся. У нас в одном месте на сайте появился SPA — и в нём мы для разных роутов подключаем разные реакт-приложения (под каждый роут своё).

До появления SPA проблем не было: при навигации происходила полная перезагрузка страницы и метрики web vitals начинали собираться заново. У нас были данные по метрике INP для каждого отдельного реакт-приложения. И если где-то что-то начинало проседать, то мы могли более точно понять, в каком из приложений проблема.

Теперь такой возможности нет. Браузер начинает считать метрику INP при заходе пользователя в данный раздел. При переходах между роутами метрика продолжает считаться как будто это всё ещё изначальная страница. И её нельзя обнулить или сбросить.

Таким образом, мы теперь видим метрику INP для всего SPA, а не для каждого отдельного реакт-приложения. Из-за этого на графиках значение метрики более сглаженное, и тяжелей понять, есть ли проблема в конкретном роуте.

Поиск решения проблемы

Пробовал найти решение для данного кейса, но кажется, такое пока нельзя реализовать.

В пакете web-vitals есть issue на эту тему. Его завели ещё аж в 2021 году. Тогда авторы библиотеки ответили, что веб-вайтелс считаются только в рамках hard навигации, так как в браузере нет механизма, с помощью которого можно однозначно понять, что произошла soft навигация: все реализуют её по-разному — кто-то пушит новые записи в объект history, кто-то просто меняет хэши в url.

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

Затем в 2024 году разработчики библиотеки сообщили, что проводят эксперименты по сбору метрик из SPA и даже можно обкатать у себя локально.

Сбор INP из SPA (пока только под флагом)

Для этого нужно перейти в раздел флагов хрома и включить фичу “Experimental Web Platform features” — хром начнёт учитывать soft навигации. Это можно сделать перейдя по ссылке chrome://flags/#enable-experimental-web-platform-features.

Далее нужно установить экспериментальную версию пакета web-vitals, умеющую работать с soft навигацией:

npm install web-vitals@5.0.1-soft-navs

Затем нужно в конфиг сбора метрик докинуть дополнительный флаг reportSoftNavs:

import { onINP } from 'web-vitals';

const sendToBackend = (data) => {
  // сохраняем данные на бэкенд
}

onINP(sendToBackend, { reportSoftNavs: true });

И всё, сбор метрик из SPA приложений начинает работать!

Проверил на нашем проекте, всё ок. Для soft навигации мы пушим новые записи в history. После перехода на новый роут метрика INP обнуляется и начинает учитывать новые события.

Итоги

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

Но надеюсь, что всё будет пучком, и скоро мы сможем считать метрики web vitals и для SPA приложений!

Полезные ссылки