Найти в Дзене
Nuances of programming

Тестирование производительности приложения в браузере Chrome

В процессе разработки часто возникает потребность протестировать в браузере производительность приложения. Такое тестирование способствует обнаружению потенциальных ошибок, замедляющих его работу.
Оглавление

Источник: Nuances of Programming

Введение

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

Образец приложения

В нашем случае используется простое приложение, включающее в себя панель приложения, плавающую кнопку действия и бесконечный список элементов, который также показывает число нажатий кнопки.

-2

У приложения есть вторая страница, содержащая определенную информацию.

-3

Скопировать приложение можно здесь:

Что будем тестировать?

Наша цель  —  протестировать производительность приложения в следующих сценариях использования:

  1. Пользователь прокручивает бесконечный список.
  2. Пользователь переключается между двумя страницами.
  3. Пользователь нажимает плавающую кнопку действия.

Установка фреймворка

К pubspec.yaml добавьте следующее:

Эта зависимость входит в минимальный пакет web_benchmarks_framework, выполняющий тестирование производительности в Chrome.

Он сформирован из macrobenchmarks и devicelab  —  двух пакетов, используемых Flutter для веб-тестирования производительности во Flutter Gallery. В настоящее время оба этих пакета применяются для аналогичного тестирования во flutter/flutter, поэтому проще импортировать более общий пакет web_benchmarks_framework.

Выполните flutter pub get, чтобы присоединить этот пакет.

Написание первого теста

Под lib добавьте директорию benchmarks, а к ней  —  файл .dart с именем runner.dart:

-4

Содержит этот файл следующее:

Что делает этот тест?

  • При запуске этого приложения создается объект ScrollRecorder, который управляет приложением, выполняя автоматические жесты. В нашем случае он начинает прокручивать бесконечный список.
  • Класс ScrollRecorder расширяет класс AppRecorder, в свою очередь расширяющий класс WidgetRecorder, который по мере управления приложением также записывает показатели производительности.
  • runBenchmarks  —  это функция, определяемая в package:web_benchmarks_framework/driver.dart, которая позволяет пользователю выбрать, какой тест выполнять, и отображает результаты в браузере.
  • Метод automate использует пакет flutter_test, предоставляющий способы выполнения жестов или поиска определенных виджетов в приложении.

Выполнение первого теста

В корневой директории проекта выполните flutter run -d chrome -t lib/benchmarks/runner.dart. Таким образом вы укажите Flutter использовать в качестве входной точки не main.dart, а runner.dart.

-5

На данный момент у нас есть всего один тест производительности, так что запустите его нажатием “scroll”.

-6

После запуска теста список начинает автоматически прокручиваться вниз.

Спустя несколько секунд тест заканчиваетсяи выводит на экран следующий результат:

-7

Этот график показывает время, затраченное приложением на отрисовку каждого (зарегистрированного) кадра. Горизонтальная ось отображает ход времени, а вертикальная  —  продолжительность каждого кадра.

Первые 2/3 графика окрашены в серый фон  —  эти кадры считаются “подготовительными” и в статистику не включаются. Такие кадры обычно обеспечивают JIT-компилятору время для компиляции кода и заполняют различные кэши, чтобы показатели измеренных кадров отражали “итоговую” производительность приложения, а не только первых секунд его работы. Тем не менее подготовительным этапом не всегда следует пренебрегать, поскольку он может предоставить ценную информацию о производительности приложения в течение первых секунд его выполнения, благодаря чему уже можно будет делать выводы о его работоспособности.

Красные кадры  —  это “выбросы”, отрисовка которых требует гораздо больше времени. Некоторые из них могут быть почти незаметными. Например, до определенного момента не будет видно подвисаний в начале или конце анимации. А вот заторможенный кадр в середине анимации будет сложно не заметить.

Выбросы служат хорошим индикатором имеющихся неполадок. Дорабатывая приложение, вы можете уменьшить значения выбросов или сократить их число, что будет свидетельствовать о повышении его плавности.

Сбор данных из Chrome DevTools

Данный тест производительности полностью выполняется внутри Chrome. Добавьте следующий файл в качестве test/run_benchmarks.dart:

Затем запустите dart test/run_benchmarks.dart.

Спустя минуту вы увидите следующие результаты:

Точные значения теста производительности могут варьироваться в зависимости от компьютера.

Что делает этот тест?

  • При выполнении test/run_benchmarks.dart собирается веб-приложение, затем запускается экземпляр Chrome, в котором это приложение выполняется.
  • После этого test/run_benchmarks.dart соединяется с портом Chrome DevTools, собирая и извлекая из него соответствующие показатели производительности.

Что означают результаты теста?

  • При отображении кадра происходит двойной обход дерева слоев.
  • “Preroll”  —  это первый обход. Он ничего не отображает, но вычисляет значения, которые позже используются для отрисовки. Примеры включают: матрицы преобразований, обратные преобразования и обрезку кадров.
  • “Apply frame”  —  это второй обход, при котором отображается UI.
  • “Draw frame”  —  это общее время, необходимое фреймворку для отображения кадра. Этот этап включает “Preroll” и “Apply frame”, а также время, затраченное на создание и расположение виджетов.
  • “Total UI frame” включает все составляющие компоненты “Draw frame”, а также скрытую работу, выполняемую браузером: обновления дерева слоев, пересчет стилей и браузерный макет (не путать с собственным макетом Flutter).
  • Когда набор данных (список временных интервалов) собран, алгоритм удаляет выбросы.
  • Сначала вычисляются среднее и стандартное отклонения данных, и любая точка данных, превышающая эти значения (среднее + 1 стандартное отклонение), считается выбросом.
  • Затем с помощью среднего и стандартного отклонения данных без выбросов (чистых данных) вычисляются средние значения и шум всего набора, которые впоследствии сообщаются.
  • Кроме того, сообщается средний показатель всех выбросов, а также отношение этого показателя к чистым данным.
  • Показатели “outlierRatio” и “noise” для каждого набора данных отчетливо указывают, сколько шума содержится в производительности приложения. Наличие чрезмерного шума свидетельствует о проблемах с последовательностью выполнения (например, торможение кадров в результате задержек сборки мусора). Уменьшив шум, вы сможете повысить плавность работы приложения.

Добавляем больше тестов

Отредактируйте lib/benchmarks/runner.dart, чтобы добавить еще два теста.

Сначала измените функцию main:

Затем добавьте еще два класса, расширяющих AppRecorder:

Что делают эти тесты?

  • Мы добавили два оставшихся теста: один проверяет переключение между страницами, другой  —  касание плавающей кнопки действия.
  • animationStops систематически контролирует выполнение анимации и останавливается по мере ее полного прекращения. Это гарантирует, например, успешный переход на страницу “about”.
  • В тестах для проверки “page” и “tap” логический тип _completed отслеживает завершение автоматических жестов.
  • В указанных тестах переопределение метода shouldContinue приводит к тому, что AppRecorder останавливает запись кадров после завершения всех жестов.

Как выполнять эти тесты?

Для запуска этих тестов (и просмотра анимации) в Chrome выполните:

  • flutter run -d chrome -t lib/benchmarks/runner.dart --profile.

Для запуска данных тестов и сбора данных DevTools выполните:

  • dart test/run_benchmarks.dart.

Что дальше?

Теперь, владея способом сбора данных производительности, вы можете использовать его по своему усмотрению:

  • Вы можете настроить задачу в CI, запускающую эти тесты производительности каждый раз, как кто-нибудь отправляет PR, чтобы избежать внесения изменений, сильно влияющих на производительность.
  • Вы также можете настроить информационную панель, отслеживающую тенденции тестов производительности.

Читайте также:

Читайте нас в Telegram, VK

Перевод статьи Tianguang Zhang: Performance testing on the web