Web Vitals предоставляет API для измерения ключевых показателей производительности пользовательского опыта: Largest Contentful Paint (LCP), First Input Delay (FID), Cumulative Layout Shift (CLS) и другие метрики. Одним из важных аспектов работы с этими метриками является сбор attribution-данных — информации о том, где и как произошли события, которые влияют на показатели, и что их вызвало. Эти данные критичны для диагностики и оптимизации производительности.
Attribution-данные включают:
click, layout-shift).Эти данные позволяют выявлять узкие места в рендеринге и интерактивности страницы, а также понять, какие элементы наиболее критичны для пользовательского опыта.
web-vitals для логированияБиблиотека web-vitals экспортирует функции для измерения
каждой ключевой метрики. Основные функции:
import { getCLS, getFID, getLCP } from 'web-vitals';
Каждая функция принимает callback, в который передается объект с метрикой, содержащий как базовые значения, так и атрибутивные данные:
getLCP((metric) => {
console.log('LCP Value:', metric.value);
console.log('Attribution Data:', metric.entries);
});
metric.value — численное значение метрики (например,
миллисекунды для LCP или FID).metric.entries — массив событий, которые вызвали
метрику, с детализацией для диагностики.Для LCP объект события
(PerformanceEntry) содержит:
element — DOM-элемент, который стал LCP.startTime — момент, когда элемент был впервые
визуализирован.url — источник ресурса (например, URL
изображения).size — размер элемента в пикселях, влияющий на
метрику.Для CLS attribution включает:
sources — список элементов, вызвавших сдвиг.node — DOM-узел, на который приходится сдвиг.previousRect и currentRect — координаты
элемента до и после изменения.Для FID данные включают:
target — элемент, на который пользователь кликнул или
коснулся.startTime и processingStart — время начала
события и момент, когда браузер начал обработку.Для полноценной диагностики необходимо сохранять
attribution-данные на сервер. Пример отправки с помощью
fetch:
function sendMetricToServer(metric) {
fetch('/collect-metrics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: metric.name,
value: metric.value,
entries: metric.entries.map(entry => ({
element: entry.element ? entry.element.tagName : null,
url: entry.url || null,
startTime: entry.startTime,
size: entry.size || null
})),
timestamp: Date.now()
})
});
}
getLCP(sendMetricToServer);
getCLS(sendMetricToServer);
getFID(sendMetricToServer);
Такой подход обеспечивает:
userAgent, размере окна и сети для выявления
зависимостей.getLCP((metric) => {
const lcpEntry = metric.entries[metric.entries.length - 1]; // Последний LCP элемент
const logData = {
metric: 'LCP',
value: metric.value,
elementTag: lcpEntry.element ? lcpEntry.element.tagName : null,
elementId: lcpEntry.element ? lcpEntry.element.id : null,
url: lcpEntry.url || null,
startTime: lcpEntry.startTime,
size: lcpEntry.size
};
console.log('LCP Attribution:', logData);
});
Такой подход дает полное понимание того, какие элементы влияют на ключевые метрики и как они распределяются по странице.