Библиотека Web Vitals предоставляет интерфейс для сбора ключевых показателей производительности веб-страниц, таких как LCP (Largest Contentful Paint), FID (First Input Delay), CLS (Cumulative Layout Shift) и TTFB (Time to First Byte). В крупных проектах, где требуется отправлять данные на сервер аналитики, эффективным подходом является объединение нескольких метрик в один запрос (batching). Это позволяет снизить сетевую нагрузку и уменьшить задержку отправки данных.
Batching основан на двух основных принципах:
Агрегация данных перед отправкой Вместо того чтобы отправлять каждую метрику в отдельном HTTP-запросе, метрики накапливаются в локальной структуре данных (например, массиве объектов), а затем отправляются одной порцией через fetch или navigator.sendBeacon.
Таймаут или триггер на событие Отправка данных выполняется либо после накопления определённого количества метрик, либо через промежуток времени. Это предотвращает слишком частые запросы и обеспечивает регулярную передачу данных.
Для удобства можно использовать следующую структуру:
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 – время фиксации метрикиЭта структура позволяет легко агрегировать данные перед отправкой.
Для отправки пакета метрик можно использовать два подхода:
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 задаёт количество метрик в одном
запросе.const BATCH_INTERVAL = 5000; // миллисекунды
setInterval(() => {
if (metricsQueue.length > 0) sendBatch();
}, BATCH_INTERVAL);
Библиотека 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.Некоторые метрики, например 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);
}
Для минимизации нагрузки:
navigator.sendBeacon для
отправки данных при выгрузке страницы.JSON.stringify с минимизацией ключей).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); // вернуть в очередь при ошибке
}
}