Данные производительности
API производительности измеряет и предоставляет данные производительности, которые можно собирать в качестве метрик производительности вашего веб-приложения. Он предоставляет методы для наблюдения за аспектами производительности приложения. Он не предоставляет анализ данных производительности или визуализации. Однако API производительности хорошо интегрирован с инструментами разработчика в браузерах, и его данные часто отправляются в конечные точки аналитики и библиотеки для записи метрик производительности, которые помогают вам оценить данные, чтобы найти узкие места в производительности, влияющие на ваших пользователей.
Эта страница предоставляет обзор того, какие данные API производительности существуют, как они собираются и как к ним можно получить доступ.
Сбор данных
Большинство метрик, предоставляемых API производительности, автоматически собираются браузером, и вам не нужно говорить ему это делать: вам просто нужно их получить.
Для некоторых метрик вам нужно указать браузеру, что измерять:
- метрика Временные метрики элементов измеряет время, необходимое для загрузки и отрисовки определенных элементов DOM. Эта метрика подключается по желанию: чтобы попросить браузер включить метрики для конкретного элемента, вы должны добавить атрибут
elementtimingк нему. - метрика Временные метрики пользователя позволяет вам измерять время между произвольными точками в вашей программе, которые могут соответствовать операциям, определяемым приложением (например, регистрации пользователя). Для сбора этих метрик вам необходимо добавить вызовы API производительности в соответствующие точки.
- метрика Временные метрики сервера позволяет вам измерять время, затраченное на операции, определяемые приложением на стороне сервера. Для сбора этих метрик ваш сервер должен отправить заголовок
Server-TimingHTTP.
Структура данных производительности
С помощью API производительности вы можете собирать данные производительности как в контексте глобального объекта Window, так и в контексте глобального объекта Worker. Если вы собираете метрики производительности для нескольких контекстов, обратите внимание на performance.timeOrigin для синхронизации временных начал между контекстами.
В этих контекстах отдельные данные производительности представлены записями производительности.
Записи производительности
Одна записанная точка данных производительности называется записью производительности и представляется экземпляром интерфейса PerformanceEntry.
API производительности записывает различные типы данных производительности, и у PerformanceEntry есть свойство entryType, которое представляет собой строку, описывающую тип этой записи производительности:
-
"element"записывает, сколько времени занимает загрузка и отрисовка элемента. -
"event"записывает, сколько времени потребовалось браузеру для начала выполнения обработчика событий в ответ на его триггер, и сколько времени заняло выполнение обработчика событий. Используется для измерения взаимодействия с последующей отрисовкой. -
"first-input"записывает задержку первого ввода. -
"largest-contentful-paint"записывает максимальную отрисовку во время загрузки страницы. -
"layout-shift"записывает метрику, представляющую, насколько сдвинулось расположение страницы в каждом кадре анимации. -
"longtask"записывает задачи, которые заняли 50 мс или более. -
"mark"записывает пользовательскую метку времени, созданную разработчиком. -
"measure"записывает пользовательское измерение между двумя метками времени, созданное разработчиком. -
"navigation"записывает метрики, связанные с переходом на страницу и начальной загрузкой. -
"paint"записывает ключевые моменты отрисовки во время загрузки страницы. -
"resource"записывает время, которое потребовалось браузеру для получения ресурса. -
"visibility-state"записывает моменты изменения состояния видимости страницы, то есть когда вкладка меняет фокус на фоновый или наоборот.
Подклассы записей производительности
Определенные типы записей обычно включают дополнительные данные, специфичные для типа: например, тип "resource" захватывает время начала и окончания поиска DNS. Таким образом, записи представлены подклассами, расширяющими базовый интерфейс PerformanceEntry. Например, запись "resource" представлена экземпляром PerformanceResourceTiming, который наследуется от PerformanceEntry, и который добавляет свойства для записи временных меток поиска DNS.
Подклассы PerformanceEntry также определяют семантику свойств, принадлежащих самому PerformanceEntry: например, у PerformanceEntry есть свойство name, смысл которого зависит от подкласса.
Следующие интерфейсы наследуются от PerformanceEntry:
LargestContentfulPaintLayoutShiftPerformanceElementTimingPerformanceEventTimingPerformanceLongTaskTimingPerformanceMarkPerformanceMeasurePerformancePaintTiming-
PerformanceResourceTiming-
PerformanceNavigationTimingнаследуется отPerformanceResourceTiming
-
TaskAttributionTimingVisibilityStateEntry
Доступ к данным
Вы можете получить доступ к записям производительности двумя способами. Предпочтительный способ — использовать интерфейс PerformanceObserver, который создается с помощью функции обратного вызова, которая вызывается при записи конкретных записей производительности. Затем вы вызываете его метод observe, передавая типы для наблюдения и используя опцию buffered, чтобы получить записи, которые произошли до наблюдения.
function logEventDuration(entries) {
const events = entries.getEntriesByType("event");
for (const event of events) {
console.log(
`Event handler took: ${
event.processingEnd - event.processingStart
} milliseconds`,
);
}
}
const observer = new PerformanceObserver(logEventDuration);
observer.observe({ type: "event", buffered: true });
В качестве альтернативы вы можете использовать методы Performance.getEntries(), Performance.getEntriesByName() и Performance.getEntriesByType() для получения всех записей производительности для страницы или записей, соответствующих заданному имени или типу.
const events = performance.getEntriesByType("event");
for (const event of events) {
console.log(
`Event handler took: ${
event.processingEnd - event.processingStart
} milliseconds`,
);
}
Опция PerformanceObserver предпочтительнее, потому что:
- методы
getEntries*всегда возвращают все соответствующие записи с начала временной шкалы, поэтому, если вы вызовете их дважды, вы увидите те же записи снова и вам нужно будет отфильтровать те записи, которые вы уже видели. - уведомления об изменениях наблюдателя доставляются асинхронно, поэтому браузер может отправлять их во время простоя, чтобы свести к минимуму их влияние на производительность.
- не все типы записей работают с методами
getEntries*. Для некоторых из них вы должны использовать наблюдатели производительности, чтобы получить к ним доступ.
Управление размерами буфера
Существует предел буфера для записей производительности для каждого глобального объекта. Он гарантирует, что браузер не потребляет неопределенное количество памяти при хранении данных производительности. Особенно, когда ваш веб-сайт или приложение извлекают много ресурсов (например, при использовании опроса), вам может потребоваться изучить пределы для буферов:
entryType идентификатор | Интерфейс | Максимальное количество записей буфера |
|---|---|---|
"mark" | PerformanceMark | Без ограничений |
"measure" | PerformanceMeasure | Без ограничений |
"navigation" | PerformanceNavigationTiming | Без ограничений |
"resource" | PerformanceResourceTiming | 250 (настраиваемое, см. ниже) |
"longtask" | PerformanceLongTaskTiming | 200 |
"paint" | PerformancePaintTiming | 2 (больше не будет) |
"element" | PerformanceElementTiming | 150 |
"event" | PerformanceEventTiming | 150 |
"first-input" | PerformanceEventTiming | 1 (больше не будет) |
"layout-shift" | LayoutShift | 150 |
"largest-contentful-paint" | LargestContentfulPaint | 150 |
"visibility-state" | VisibilityStateEntry | 50 |
Таблица 1. Размеры буферов (источник).
Для типов записей "resource" см. Управление размерами буфера ресурсов для того, как установить другой размер буфера.
Для "first-input" и "paint" ограничение заложено в определении метрики. Больше одной (или двух) записей не будет.
Обратный вызов наблюдателя производительности содержит необязательный параметр droppedEntriesCount, который сообщает вам, сколько записей было потеряно из-за заполненного буфера хранения.
function perfObserver(list, observer, droppedEntriesCount) {
list.getEntries().forEach((entry) => {
// do something with the entries
});
if (droppedEntriesCount > 0) {
console.warn(
`${droppedEntriesCount} entries were dropped because the buffer was full.`,
);
}
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ type: "resource", buffered: true });
Еще один полезный метод — PerformanceObserver.takeRecords(), который возвращает текущий список записей производительности, сохраненных в наблюдателе производительности, а также очищает его.
Данные JSON
Все записи производительности предоставляют toJSON() сериализатор, который возвращает JSON представление записи. Это может быть полезно, если вы хотите собрать все доступные данные и сохранить их где-либо.
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log(entry.toJSON());
});
});
observer.observe({ type: "event", buffered: true });
Это выведет объект JSON примерно так:
{
"name": "dragover",
"entryType": "event",
"startTime": 67090751.599999905,
"duration": 128,
"processingStart": 67090751.70000005,
"processingEnd": 67090751.900000095,
"cancelable": true
}
Чтобы получить строковое представление записи, вы можете использовать JSON.stringify(entry) с любым PerformanceEntry объектом напрямую; он автоматически вызовет метод toJSON() записи.
См. также
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Performance_data