Наблюдатель производительности — эффективный доступ к данным о производительности

Прогрессивные веб-приложения позволяют разработчикам создавать новый класс приложений, обеспечивающих надежный и высокопроизводительный пользовательский интерфейс. Но чтобы быть уверенным, что веб-приложение достигает желаемых показателей производительности, разработчикам необходим доступ к данным измерения производительности с высоким разрешением. Спецификация W3C Performance Timeline определяет такой интерфейс для браузеров, обеспечивающий программный доступ к данным синхронизации низкого уровня. Это открывает двери для некоторых интересных вариантов использования:

  • оффлайн и индивидуальный анализ производительности
  • сторонние инструменты анализа и визуализации производительности
  • оценка производительности интегрирована в IDE и другие инструменты разработчика

Доступ к такого рода временным данным уже доступен в большинстве основных браузеров для определения времени навигации , времени использования ресурсов и времени пользователя . Новейшим дополнением является интерфейс наблюдателя производительности , который по сути представляет собой потоковый интерфейс для асинхронного сбора информации о времени низкого уровня по мере ее сбора браузером. Этот новый интерфейс предоставляет ряд важных преимуществ по сравнению с предыдущими методами доступа к временной шкале:

  • Сегодня приложениям приходится периодически опрашивать и сравнивать сохраненные измерения, что обходится дорого. Этот интерфейс предлагает им обратный вызов. (Другими словами, нет необходимости проводить опрос). В результате приложения, использующие этот API, могут быть более отзывчивыми и эффективными.
  • На него не распространяются ограничения буфера (большинство буферов по умолчанию имеют значение 150 элементов) и позволяют избежать состояний гонки между различными потребителями, которые могут захотеть изменить буфер.
  • Уведомления наблюдателя за производительностью доставляются асинхронно, и браузер может отправлять их во время простоя, чтобы избежать конкуренции с критически важной работой по рендерингу.

Начиная с Chrome 52, интерфейс наблюдателя производительности включен по умолчанию . Давайте посмотрим, как его использовать.

<html>
<head>
    <script>
    var observer = new PerformanceObserver(list => {
        list.getEntries().forEach(entry => {
        // Display each reported measurement on console
        if (console) {
            console.log("Name: "       + entry.name      +
                        ", Type: "     + entry.entryType +
                        ", Start: "    + entry.startTime +
                        ", Duration: " + entry.duration  + "\n");
        }
        })
    });
    observer.observe({entryTypes: ['resource', 'mark', 'measure']});
    performance.mark('registered-observer');

    function clicked(elem) {
        performance.measure('button clicked');
    }
    </script>
</head>
<body>
    <button onclick="clicked(this)">Measure</button>
</body>
</html>

Эта простая страница начинается с тега скрипта, определяющего некоторый код JavaScript:

  • Мы создаем экземпляр нового объекта PerformanceObserver и передаем функцию обработчика событий конструктору объекта. Конструктор инициализирует объект таким образом, что наш обработчик будет вызываться каждый раз, когда новый набор данных измерений будет готов к обработке (при этом данные измерений передаются в виде списка объектов). Обработчик здесь определен как анонимная функция, которая просто отображает отформатированные данные измерений на консоли. В реальном сценарии эти данные могут храниться в облаке для последующего анализа или передаваться в интерактивный инструмент визуализации.
  • Мы регистрируем интересующие нас типы временных событий с помощью метода observe() и вызываем метод mark() , чтобы отметить момент регистрации, который мы будем считать началом наших временных интервалов.
  • Мы определяем обработчик кликов для кнопки, определенной в теле страницы. Этот обработчик кликов вызывает метод measure() для сбора данных о времени нажатия кнопки.

В теле страницы мы определяем кнопку, назначаем обработчик кликов событию onclick , и все готово.

Теперь, если мы загрузим страницу и откроем панель Chrome DevTools, чтобы просмотреть консоль JavaScript, каждый раз, когда мы нажимаем кнопку, будет измеряться производительность. И поскольку мы зарегистрировались для наблюдения за такими измерениями, они асинхронно пересылаются нашему обработчику событий без необходимости опроса временной шкалы , которая отображает измерения на консоли по мере их возникновения:

Наблюдатель за производительностью.

start значение представляет собой начальную метку времени для событий типа mark (из которых в этом приложении есть только одно). События с measure типа не имеют собственного времени начала; они представляют собой измерения времени, сделанные относительно последнего события mark . Таким образом, значения длительности, показанные здесь, представляют собой время, прошедшее между вызовом mark() , который служит начальной точкой общего интервала, и несколькими последующими вызовами measure() .

Как видите, этот API довольно прост и предлагает возможность собирать отфильтрованные данные о производительности в высоком разрешении в реальном времени без опроса, что должно открыть путь к более эффективным инструментам повышения производительности для веб-приложений.