Batching нескольких метрик в одном запросе

Библиотека Web Vitals предоставляет интерфейс для сбора ключевых показателей производительности веб-страниц, таких как LCP (Largest Contentful Paint), FID (First Input Delay), CLS (Cumulative Layout Shift) и TTFB (Time to First Byte). В крупных проектах, где требуется отправлять данные на сервер аналитики, эффективным подходом является объединение нескольких метрик в один запрос (batching). Это позволяет снизить сетевую нагрузку и уменьшить задержку отправки данных.


Принципы работы batching

Batching основан на двух основных принципах:

  1. Агрегация данных перед отправкой Вместо того чтобы отправлять каждую метрику в отдельном HTTP-запросе, метрики накапливаются в локальной структуре данных (например, массиве объектов), а затем отправляются одной порцией через fetch или navigator.sendBeacon.

  2. Таймаут или триггер на событие Отправка данных выполняется либо после накопления определённого количества метрик, либо через промежуток времени. Это предотвращает слишком частые запросы и обеспечивает регулярную передачу данных.


Организация структуры данных для batching

Для удобства можно использовать следующую структуру:

const metricsQueue = [];

function addMetric(metric) {
    metricsQueue.push({
        name: metric.name,
        value: metric.value,
        id: metric.id,
        timestamp: Date.now()
    });
}

Каждая метрика содержит:

  • name – название показателя (LCP, FID, CLS и т.д.)
  • value – числовое значение метрики
  • id – уникальный идентификатор события
  • timestamp – время фиксации метрики

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


Настройка отправки данных

Для отправки пакета метрик можно использовать два подхода:

1. По достижении лимита

const MAX_BATCH_SIZE = 5;

function sendBatch() {
    if (metricsQueue.length === 0) return;

    const batch = metricsQueue.splice(0, MAX_BATCH_SIZE);
    navigator.sendBeacon('/analytics', JSON.stringify(batch));
}
  • splice удаляет из очереди отправленные метрики, чтобы избежать повторной отправки.
  • MAX_BATCH_SIZE задаёт количество метрик в одном запросе.

2. По таймауту

const BATCH_INTERVAL = 5000; // миллисекунды

setInterval(() => {
    if (metricsQueue.length > 0) sendBatch();
}, BATCH_INTERVAL);
  • Этот подход гарантирует регулярную отправку данных, даже если количество метрик не достигло лимита.
  • Оптимально использовать комбинацию лимита и таймаута, чтобы избежать задержки и перегрузки сети.

Интеграция с Web Vitals

Библиотека Web Vitals предоставляет функцию getCLS, getFID, getLCP, каждая из которых принимает callback:

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

getCLS(metric => addMetric(metric));
getFID(metric => addMetric(metric));
getLCP(metric => addMetric(metric));
  • Метрики автоматически передаются в очередь metricsQueue.
  • Далее срабатывает механизм batching.

Учет повторных событий

Некоторые метрики, например CLS, могут изменяться несколько раз за жизненный цикл страницы. Чтобы корректно отправлять данные:

  • Использовать уникальные идентификаторы событий
  • Сохранять историю отправленных значений
  • Включать версию страницы или сессию для анализа
function addMetric(metric) {
    const entry = {
        name: metric.name,
        value: metric.value,
        id: metric.id,
        timestamp: Date.now(),
        page: window.location.pathname
    };
    metricsQueue.push(entry);
}

Оптимизация сети

Для минимизации нагрузки:

  1. Использовать navigator.sendBeacon для отправки данных при выгрузке страницы.
  2. Сжимать payload перед отправкой (например, через JSON.stringify с минимизацией ключей).
  3. Объединять метрики нескольких страниц в единую очередь при SPA-приложениях.
  4. Обрабатывать ошибки сети и ретрай при необходимости:
async function sendBatch() {
    if (metricsQueue.length === 0) return;

    const batch = metricsQueue.splice(0, MAX_BATCH_SIZE);
    try {
        await fetch('/analytics', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(batch)
        });
    } catch (err) {
        metricsQueue.unshift(...batch); // вернуть в очередь при ошибке
    }
}

Преимущества batching

  • Снижение количества сетевых запросов
  • Более высокая точность данных за счёт уменьшения потерь при медленных сетях
  • Удобство анализа, так как данные приходят пакетами