[Перевод] Как отслеживать производительность веб-приложения с JavaScript и Performance API

В сентябре этого года у меня была возможность присоединиться к Forest Admin, компании, которая выполняет всю тяжёлую работу по созданию панели администратора любого веб-приложения и предоставляет платформу на основе API, чтобы реализовать все ваши конкретные бизнес-процессы. Моей первой задачей было реализовать мониторинг времени загрузки приложения, а также мониторинг времени запросов, сделанных нашими клиентами в их административном бэкенде, который я разработал.

Цель такой функции – иметь возможность ориентироваться на проекты, работая с которыми пользователи сталкиваются с длительной загрузкой, чтобы оптимизировать конфигурацию своего интерфейса. Это делает навигацию и взаимодействие с приложением плавнее и, таким образом, улучшает взаимодействие с пользователем. Для этого первым делом нужно выяснить, как мы собираемся реализовать такую функцию.


В зависимости от используемой среды разработки надстройки могут уже быть установлены. Если вы разработчик React, например, react-addons-per. должен позволить вам отслеживать то, что вы хотите. В Forest Admin мы используем Ember.js, и нет никакой надстройки, подобной React. Поэтому воспользуемся Performance API, который, согласно документации, должен позволить нам сделать именно то, что мы хотим сделать:

Стандарт High Resolution Time определяет интерфейс производительности, который поддерживает измерения задержки на стороне клиента в приложениях. Интерфейсы Performance считаются интерфейсами с высоким разрешением, поскольку имеют точность до тысячных долей миллисекунды (в зависимости от аппаратных или программных ограничений).

II. API Performance


Performance API использует множество разнообразных методов. Нам понадобится всего 5:

  • mark;
  • measure;
  • getEntriesByType;
  • clearMarks/clearMeasures.

1. mark


Метод mark позволяет разместить маркер времени. Чтобы сослаться на маркер, требуется только один аргумент (строка), этот метод ничего не возвращает. Позже он позволит рассчитать время.

performance.mark('start');

2. measure


Метод measure позволяет измерить разницу во времени между двумя маркерами. Он принимает 3 аргумента: имя созданного измерителя (строка), маркер начала (строка), маркер конца (строка). Этот метод возвращает объект со свойством duration, которое вычисляет разницу между двумя маркерами.

async function timeDuration() {
    performance.mark('start');
    await new Promise(resolve => setTimeout(resolve, 100))
    performance.mark('end');
  
    return performance.measure('time', 'start', 'end').duration;
  }
  
  timeDuration().then((result) => console.log(result));
  // output: 100

3. getEntriesByType


Метод getEntriesByType позволяет получить доступ ко всем созданным объектам определённого типа. Он возвращает массив объектов и принимает в качестве аргумента тип входных значений (строку) из следующих: frame, navigation, resource, mark, measure, paint, longtask. Не волнуйтесь, нам понадобятся только mark и measure.

performance.getEntriesByType('measure');
    // output: return an Array of Object containing all the measure

4. clearMarks/clearMeasures

Методы clearMarks/clearMeasures используются для удаления ранее добавленных маркеров и измерителей из кеша браузера. Эти методы ничего не возвращают и не принимают никаких аргументов.

III. Давайте углубимся в код

Теперь, когда мы знаем методы реализации функциональности, нам нужно интегрировать её в код. У нас есть два варианта: создать маркеры и проводить измерения прямо в нужных местах кода или создать сервис (time-tracker.js) и вставить его в код. Для наглядности выберем второй вариант.

performance.mark('start');
    performance.mark('end');
    performance.measure('time_duration', 'start', 'end');
    
    console.log(performance.getEntriesByType('mark').length);
    // output: 2
    console.log(performance.getEntriesByType('measure').length);
    // output: 1
    
    performance.clearMarks();
    performance.clearMeasures();
    console.log(performance.getEntriesByType('mark').length);
    // output: 0
    console.log(performance.getEntriesByType('measure').length);
    // output: 0

Всё просто, правда? Теперь нам нужно вызвать сервисные функции в тех местах кода, которые позволят нам отслеживать время загрузки запроса и интерфейса. Для интерфейса маркер timinginterfacestart должен вызываться в начале загрузки страницы. Первым вызывается метод model маршрута, который разместим здесь. Также возможно использовать методы в жизненных циклах компонента или любой другой функции, вызванной изначально. Однако следует соблюдать осторожность при размещении маркера. Если маркер не поставить в нужное место, последующее измерение будет неточным.

import { inject as service } from '@ember/service';

    export default class RouteExample extends Route {
      @service timeTracker;
      
      model() {
        this.timeTracker.startInterface();
        // do something
      }
    }

Для маркера timinginterfacestop он должен вызываться, когда закончен рендеринг приложения. Что касается рендеринга нескольких компонентов, логичным способом является использование методов в жизненных циклах этих компонентов. Метод компонента didRender из ember кажется хорошим кандидатом. Затем идёт измерение общего времени загрузки интерфейса. Его можно разместить после маркера timinginterfacestop или в любом другом желаемом месте.

import { inject as service } from '@ember/service';

    export default class RenderingTracker extends Component {
      @service timeTracker;
    
      didRender() {
        this.timeTracker.stopInterface();
      }
      stopInterfaceTracking() {
        return this.timeTracker.measureTimingInterface()
      }
    }

Для расчёта времени запроса на сервере пользователя достаточно окружить функцию, отвечающую за запрос сервера пользователя, маркерами timingrequeststart и Timingrequeststop. Затем можно измерить время запроса, вызвав метод measureTimingRequest() из нашего сервиса.

import { inject as service } from '@ember/service';

    export default class RouteExample extends Route {
      @service timeTracker;
      
      model() {
        this.timeTracker.startInterface();
        // do something
      }
      
      async function fetchData(params) {
        //do something
      
        this.timeTracker.startRequest();
        const records = await fetchRecords(params);
        this.timingTracker.stopRequest();
        
        const timingRequest = this.timingTracker.measureTimingRequest()
        // do something else
    
      }
    }

Заключение


Надеюсь, вам понравилась эта статья. Есть и другие возможности реализовать эту функцию. Я решил показать вам путь, который имеет для меня больше смысла. API Performance – мощный инструмент, чтобы получить информацию о производительности вашего приложения. Важно знать, сталкиваются ли пользователи с трудностями, когда просматривают ваше приложение. Более того, это позволяет вам заранее нацеливаться на проблемы, чтобы решать эти проблемы и улучшать взаимодействие с пользователем. Следующим шагом может быть интеграция дополнительного электронного письма для пользователей, время загрузки у которых превышает пороговое значение, чтобы эти пользователи могли выбрать определённые параметры оптимизации.


Другие профессии и курсы
ПРОФЕССИИ

КУРСЫ

Let’s block ads! (Why?)

Read More

Recent Posts

Apple возобновила переговоры с OpenAI и Google для интеграции ИИ в iPhone

Apple возобновила переговоры с OpenAI о возможности внедрения ИИ-технологий в iOS 18, на основе данной операционной системы будут работать новые…

5 дней ago

Российская «дочка» Google подготовила 23 иска к крупнейшим игрокам рекламного рынка

Конкурсный управляющий российской «дочки» Google подготовил 23 иска к участникам рекламного рынка. Общая сумма исков составляет 16 млрд рублей –…

5 дней ago

Google завершил обновление основного алгоритма March 2024 Core Update

Google завершил обновление основного алгоритма March 2024 Core Update. Раскатка обновлений была завершена 19 апреля, но сообщил об этом поисковик…

5 дней ago

Нейросети будут писать тексты объявления за продавцов на Авито

У частных продавцов на Авито появилась возможность составлять текст объявлений с помощью нейросети. Новый функционал доступен в категории «Обувь, одежда,…

5 дней ago

Объявлены победители международной премии Workspace Digital Awards-2024

24 апреля 2024 года в Москве состоялась церемония вручения наград международного конкурса Workspace Digital Awards. В этом году участниками стали…

6 дней ago

Яндекс проведет гик-фестиваль Young Con

27 июня Яндекс проведет гик-фестиваль Young Con для студентов и молодых специалистов, которые интересуются технологиями и хотят работать в IT.…

6 дней ago