Формирование payload и схема данных

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

Основные принципы формирования payload

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

  • name — название метрики (например, 'CLS', 'LCP', 'FID', 'INP').
  • value — числовое значение метрики, как правило, с плавающей точкой, отражающее измеряемый показатель в миллисекундах или долях секунды.
  • id — уникальный идентификатор сессии или события, позволяющий коррелировать метрики между разными страницами.
  • entries — массив детализированных записей из PerformanceObserver, содержащий полную информацию о наблюдаемых событиях.

Пример структуры payload в Jav * aScript:

{
  name: 'LCP',
  value: 1234.56,
  id: 'v1-1234567890',
  entries: [
    {
      startTime: 1200,
      renderTime: 1234,
      size: 45678,
      element: 'img.hero-banner'
    }
  ]
}

Детализация метрик через entries

Каждая метрика Web Vitals имеет собственные правила формирования entries. Например:

  • LCP (Largest Contentful Paint): entries включает объекты PerformanceEntry с типом 'largest-contentful-paint'. Поля: startTime, renderTime, element, size.
  • CLS (Cumulative Layout Shift): entries содержит объекты 'layout-shift', где фиксируются value, sources (элементы, вызвавшие сдвиг), startTime.
  • FID (First Input Delay): entries содержит объекты 'first-input', включающие startTime, processingStart, duration, target.

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

Схема данных и типизация

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

interface WebVitalsPayload {
  name: 'CLS' | 'LCP' | 'FID' | 'INP';
  value: number;
  id: string;
  entries: Array>;
}

Использование строгой схемы позволяет:

  • Избежать ошибок при сериализации данных.
  • Снизить вероятность потери критически важной информации.
  • Обеспечить совместимость с бекендом и аналитическими платформами.

Оптимизация размера payload

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

  1. Фильтрация entries — отправлять только последние события или события с наибольшим влиянием.
  2. Агрегация данных — для CLS можно суммировать значения с одного временного интервала вместо отправки всех отдельных сдвигов.
  3. Минификация ключей — в продакшн-версии можно заменить startTime на st, renderTime на rt и так далее, уменьшая размер объекта.

Интеграция с PerformanceObserver

Основной инструмент для формирования payload — PerformanceObserver, который позволяет получать события производительности в реальном времени:

import {getLCP} from 'web-vitals';

getLCP(metric => {
  const payload = {
    name: metric.name,
    value: metric.value,
    id: metric.id,
    entries: metric.entries.map(entry => ({
      startTime: entry.startTime,
      renderTime: entry.renderTime,
      element: entry.element.tagName,
      size: entry.size
    }))
  };
  sendToAnalytics(payload);
});

Ключевой момент — корректная сериализация entries, так как объекты PerformanceEntry содержат ссылки на DOM-элементы, которые нельзя напрямую отправлять в JSON. Следует использовать только сериализуемые свойства: startTime, duration, size, tagName, id.

Обеспечение уникальности идентификаторов

id метрики должен быть уникальным на уровне сессии или страницы. Используются подходы:

  • Генерация UUID для каждой страницы.
  • Использование комбинации performance.timeOrigin + Math.random().

Это позволяет связывать метрики с конкретными визитами и корректно агрегировать данные в аналитике.

Рекомендации по обработке ошибок

При формировании payload необходимо учитывать возможные исключения:

  • Отсутствие entries для метрики — формировать пустой массив.
  • Неверные типы данных — приводить к числу или строке.
  • Ошибки сериализации — логировать и не блокировать отправку других метрик.