Кратко
СкопированоPerformance API — это API браузера, которое измеряет время работы программы при помощи различных методов. Для этого используется очень точный тип измерения времени – DOM
, работающий с точностью до 5 микросекунд (в одной миллисекунде их тысяча).
Пример
СкопированоСоздание меток и измерений
СкопированоПолучаем время, прошедшее с начала навигации на страницу:
const t = performance.now()console.log(t)// 471359
const t = performance.now() console.log(t) // 471359
Создаём именованную метку времени, сохраняющую время в миллисекундах с начала навигации на страницу. Это полезно для измерения работы программы, например, можно вычислить разницу между метками и узнать время работы функции.
performance.mark('старт приложения')console.log(t)
performance.mark('старт приложения') console.log(t)
Вычисляем время между двумя метками:
const start = performance.mark('начало')const finish = performance.mark('конец')performance.measure('итого', 'начало', 'конец')console.log(performance.getEntriesByName('итого')[0].duration)// Количество миллисекунд между метками 'начало' и 'конец'
const start = performance.mark('начало') const finish = performance.mark('конец') performance.measure('итого', 'начало', 'конец') console.log(performance.getEntriesByName('итого')[0].duration) // Количество миллисекунд между метками 'начало' и 'конец'
Работа с записанными данными
СкопированоПолучаем список меток и измерений:
for (const entry of performance.getEntries()) { console.log(` Запись "${entry.name}", тип ${entry.entryType}. Старт в ${entry.startTime}мс, продолжительность ${entry.duration}мс `)}
for (const entry of performance.getEntries()) { console.log(` Запись "${entry.name}", тип ${entry.entryType}. Старт в ${entry.startTime}мс, продолжительность ${entry.duration}мс `) }
Очищаем список меток и измерений:
performance.clearMeasures()performance.clearMarks()
performance.clearMeasures() performance.clearMarks()
Очищаем всё сразу:
performance.clearResourceTimings()
performance.clearResourceTimings()
Как пишется
СкопированоСоздание меток
СкопированоМетка (mark) — время с начала перехода на страницу до создания метки в миллисекундах. Например, от клика по ссылке или после подтверждения введённого URL в строку поиска.
При создании меток мы можем передать первым аргументом строку — имя метки. В дальнейшем мы можем обращаться к этому имени для поиска.
const markName = 'старт выполнения функции'performance.mark(markName)const entries = performance.getEntriesByName(markName)console.log(entries)
const markName = 'старт выполнения функции' performance.mark(markName) const entries = performance.getEntriesByName(markName) console.log(entries)
Объект метки содержит значение mark
в поле entry
.
Создание измерений
СкопированоИзмерение (measure) — разница во времени между двумя метками. Измерение принимает несколько аргументов:
- имя измерения;
- имя первой метки — необязательный параметр; если не указать, первой меткой будет время со старта навигации на страницу;
- имя второй метки — необязательный параметр; если не указать, второй меткой будет вызов
performance
в момент создания измерения.. now ( )
В Firefox и некоторых мобильных браузерах вызов метода measure
не возвращает полученное измерение и его нужно запрашивать вручную с помощью get
. Следите за таблицей поддержки.
const markOne = 'метка_1'const markTwo = 'метка_2'performance.mark(markOne)performance.mark(markTwo)performance.measure('время со старта навигации на странице')performance.measure('от первой метки до сейчас', markOne)performance.measure('время между двумя метками', markOne, markTwo)const m1 = performance.getEntriesByName('время со старта навигации на странице')[0]const m2 = performance.getEntriesByName('от первой метки до сейчас')[0]const m3 = performance.getEntriesByName('время между двумя метками')[0]console.log({ m1, m2, m3 })
const markOne = 'метка_1' const markTwo = 'метка_2' performance.mark(markOne) performance.mark(markTwo) performance.measure('время со старта навигации на странице') performance.measure('от первой метки до сейчас', markOne) performance.measure('время между двумя метками', markOne, markTwo) const m1 = performance.getEntriesByName('время со старта навигации на странице')[0] const m2 = performance.getEntriesByName('от первой метки до сейчас')[0] const m3 = performance.getEntriesByName('время между двумя метками')[0] console.log({ m1, m2, m3 })
Способы получения меток и измерений
СкопированоПолучить измерения и метки можно тремя способами:
performance
— получить список всех меток и измерений, включая записываемые браузером.. get Entries ( ) performance
— получить список из записей заданного типа, например,. get Entries By Type ( тип ) mark
илиmeasure
.performance
— получить список из записей с указанным именем.. get Entries By Name ( имя )
Метки, автоматически записываемые браузером
Для улучшения анализа производительности страницы, браузер автоматически записывает некоторые метки:
navigation
— события навигации браузераdom
,Complete load
,Event Start load
,Event End redirect
,Count dom
,Content Loaded Event Start dom
,Content Loaded Event End dom
,Interactive request
,Start response
,Start unload
,Event End unload
.Event Start resource
— содержат информацию о загрузке ресурсов сайтом. Например, можно узнать про загрузку стилей или выполнение запросов к API.paint
— информация о рендере страницы, например, время отрисовки первого контента (first
,- paint first
).- contentful - paint
Любой из способов вернёт массив записей:
const mark = performance.mark('старт')const measure = performance.measure('прошло со старта', 'старт')const entries = performance.getEntries()const entriesByName = performance.getEntriesByName('прошло со старта')const onlyMarks = performance.getEntriesByType('mark')console.log(entries)console.log(entriesByName)console.log(onlyMarks)
const mark = performance.mark('старт') const measure = performance.measure('прошло со старта', 'старт') const entries = performance.getEntries() const entriesByName = performance.getEntriesByName('прошло со старта') const onlyMarks = performance.getEntriesByType('mark') console.log(entries) console.log(entriesByName) console.log(onlyMarks)
Способы очистить записи
СкопированоМетки и измерения с одинаковыми именами не перезаписывают друг друга. Если одно и то же имя может использоваться в разных частях кода, например, если имена создаются динамически, полезно удалять уже созданные метки перед записью новых с тем же именем. Очистить записанные метки и измерения можно несколькими методами.
performance
— очистить все записанные метки с переданным именем. Если имя не передать, удалятся все метки, созданные методом performance
.
performance
— очищаем все записанные измерения с переданным именем. Если имя не передать, удалятся все измерения, созданные методом performance
.
performance
— очистить все метки, связанные с загрузкой ресурсов браузером.
const mark = performance.mark('метка')const measure = performance.measure('измерение')console.log(performance.getEntriesByName('метка').length)// 1performance.clearMarks('метка')performance.clearMeasures('измерение')console.log(performance.getEntriesByName('метка').length)// 0performance.clearResourceTimings()
const mark = performance.mark('метка') const measure = performance.measure('измерение') console.log(performance.getEntriesByName('метка').length) // 1 performance.clearMarks('метка') performance.clearMeasures('измерение') console.log(performance.getEntriesByName('метка').length) // 0 performance.clearResourceTimings()
Как понять
СкопированоКогда нужно проверить скорость работы кода, провести тесты производительности или найти узкие места — на помощь приходит Performance API с его удобными методами и точностью измерений.
Performance API представляет собой реестр записей. Записи бывают разных типов:
mark
— именная метка времени;measure
— измерение. Продолжительность между двумя метками;element
— время загрузки элементов;navigation
— для записей, связанных с навигацией по сайту;resource
— время получение внешних ресурсов (css, запросы API);paint
— время первой отрисовки (first paint), либо первой отрисовки контента (first contentful paint);longtask
— время работы задачи из LongTasks API.
Тип записи хранится в поле entry
. В ручном режиме мы работаем с метками и измерениями.
На практике
Скопированосоветует Скопировано
🛠 Удобно анализировать производительность при помощи вкладки «Производительность» (Performance) в инструментах разработчика. Вызовы performance
и performance
отобразятся в разделе Timings
после записи профиля.
🛠 Может появиться желание написать декоратор или функцию-обёртку для performance
и performance
и обернуть в неё всё приложение. Например, так:
const withPerformanceMeasure = (markName, functionToAudit) => { performance.mark(`${markName}-before`) functionToAudit() performance.mark(`${markName}-after`) performance.measure(`${markName}-before`,`${markName}-after`)}// Тело скриптаwithPerformanceMeasure(myApp)
const withPerformanceMeasure = (markName, functionToAudit) => { performance.mark(`${markName}-before`) functionToAudit() performance.mark(`${markName}-after`) performance.measure(`${markName}-before`,`${markName}-after`) } // Тело скрипта withPerformanceMeasure(myApp)
Этого не стоит делать. Затраты на выполнение функции performance
минимальные, но не нулевые.
советует Скопировано
🛠 performance
полезно использовать для поиска узких мест вашей программы. Рассмотрим пример, когда есть две функции function
и function
и мы хотим выяснить какая из функций тормозит нашу программу.
При измерении видно, что function
работает медленнее, значит, для ускорения нужно оптимизировать её.
🛠 Инструменты разработчика отслеживают производительность программы и другими способами. Например, во вкладке «Производительность» (Performance) можно записать работу программы и проанализировать время работы отдельных функций или показатели рендеринга. В настройках инструментов разработчика включается отображение FPS (количество кадров в секунду), так проверите быстродействие интерфейса.