Библиотека Web Vitals предоставляет возможность измерять ключевые показатели производительности веб-страницы в реальном времени. Для передачи этих метрик на собственный сервер необходимо правильно организовать сбор данных, их упаковку и отправку с минимальным влиянием на производительность.
Для работы с Web Vitals необходимо установить официальный пакет:
npm install web-vitals
или подключить его через CDN:
<script src="https://unpkg.com/web-vitals"></script>
В браузере библиотека предоставляет глобальный объект
webVitals, а в Node.js/ESM используется импорт:
import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals';
Web Vitals измеряет следующие показатели:
Каждая метрика передается как объект с ключевыми свойствами:
{
name: 'LCP', // название метрики
value: 2345.67, // численное значение в миллисекундах
id: 'v1-12345', // уникальный идентификатор замера
delta: 0, // разница с предыдущим значением (для CLS)
entries: [...] // подробные записи PerformanceEntry
}
Для безопасной и эффективной передачи данных на бэкенд рекомендуется
использовать navigator.sendBeacon, если поддерживается
браузером. Этот метод отправляет данные асинхронно, не блокируя закрытие
страницы.
function sendToBackend(metric) {
const url = '/api/web-vitals';
const body = JSON.stringify({
name: metric.name,
value: metric.value,
id: metric.id,
delta: metric.delta,
entries: metric.entries
});
if (navigator.sendBeacon) {
const blob = new Blob([body], { type: 'application/json' });
navigator.sendBeacon(url, blob);
} else {
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body
}).catch(console.error);
}
}
Особенности метода sendBeacon:
Для каждой метрики нужно вызвать соответствующую функцию Web Vitals, передав коллбэк для отправки на сервер:
import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals';
getCLS(sendToBackend);
getFID(sendToBackend);
getLCP(sendToBackend);
getFCP(sendToBackend);
getTTFB(sendToBackend);
Метрики будут передаваться на сервер по мере их измерения, включая те, которые обновляются динамически (например, CLS).
Агрегация перед отправкой Если требуется минимизировать количество запросов, можно накапливать метрики в массив и отправлять их пакетами каждые N секунд:
const metricsQueue = [];
function enqueueMetric(metric) {
metricsQueue.push(metric);
if (metricsQueue.length >= 5) {
flushMetrics();
}
}
function flushMetrics() {
sendToBackend({ metrics: metricsQueue.splice(0) });
}
getCLS(enqueueMetric);
getFID(enqueueMetric);
getLCP(enqueueMetric);Дебаунс и таймаут Для событий, которые обновляются часто, используется задержка перед отправкой последней версии метрики:
let lcpTimeout;
getLCP(metric => {
clearTimeout(lcpTimeout);
lcpTimeout = setTimeout(() => sendToBackend(metric), 1000);
});Минимизация объема данных Не обязательно
отправлять весь массив entries. Для бэкенда часто
достаточно value, name и
id.
На серверной стороне необходимо принимать POST-запросы с JSON-данными:
// Пример на Node.js с Express
app.post('/api/web-vitals', express.json(), (req, res) => {
const metrics = req.body.metrics ? req.body.metrics : [req.body];
metrics.forEach(metric => {
// Сохранение в базу данных или аналитическую систему
console.log(metric.name, metric.value);
});
res.status(200).end();
});
Советы по серверной обработке:
Для полезной аналитики вместе с метриками рекомендуется отправлять дополнительную информацию:
window.location.href)Пример формирования payload:
function sendToBackend(metric) {
const payload = {
metric,
page: window.location.href,
userAgent: navigator.userAgent,
sessionId: window.sessionStorage.getItem('sessionId')
};
const blob = new Blob([JSON.stringify(payload)], { type: 'application/json' });
navigator.sendBeacon('/api/web-vitals', blob);
}
Использование sendBeacon и агрегации позволяет получать
данные в реальном времени без заметного влияния на работу страницы. Это
особенно важно для метрик, таких как FID и CLS, которые фиксируются в
момент взаимодействия пользователя или во время динамических изменений
контента.
Эта методика обеспечивает надежный сбор и передачу метрик Web Vitals на собственный бэкенд с минимальной нагрузкой на производительность и максимальной точностью данных.