Планирование и измерение производительности приложения

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

Указание целей

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

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

Задайте начальные цели, которые являются конкретными и измеримыми. Они должны быть разделены на три категории:

  • Время — сколько времени требуется пользователям или приложению для выполнения задач
  • Плавность — скорость и непрерывность, с которыми приложение перерисовывается в ответ на действия пользователя
  • Эффективность — как хорошо приложение экономит системные ресурсы, включая питание от батареи

Time

Думайте о допустимых диапазонах истекшего времени (классов взаимодействия) для пользователей для выполнения своих задач.

Класс взаимодействия Восприятие пользователя Ideal Maximum Примеры
Быстрый Минимальная заметная задержка 100 мс 200 мс Откройте панель приложения; Нажмите кнопку (первый ответ)
Нормальное Быстрая, но не скоростная 300 мс 500 мс Изменение размера; семантическое масштабирование
Адаптивный Не быстро, но чувствует себя адаптивным 500 мс 1 секунда Перейдите на другую страницу; возобновление работы приложения
Launch Конкурентный опыт 1 секунда 3 секунды Запуск приложения в первый раз
Непрерывный Больше не является отзывчивым 500 мс 5 секунд Скачивание файла из Интернета
пленённый Слишком длинно; пользователь может уйти 500 мс 10 секунд Установка нескольких приложений из Магазина

Назначьте классы взаимодействия сценариям производительности приложения. Для каждого сценария назначьте ссылку на точку во времени приложения, часть пользовательского интерфейса и класс взаимодействия.

Текучесть

Конкретные измеримые цели по плавности работы вашего приложения могут включать:

  • Без остановок и возобновлений перерисовки экрана (сбоев)
  • Анимации отображаются с частотой 60 кадров в секунду (FPS)
  • Когда пользователь сдвигает или прокручивается, приложение представляет 3–6 страниц содержимого в секунду

Efficiency

Конкретные измеримые цели эффективности для вашего приложения могут включать:

  • Загрузка ЦП вашего приложения не превышает целевое значение, а использование памяти в МБ не превышает целевой уровень в любой момент времени
  • Если приложение неактивно, использование ЦП и памяти минимальны
  • Ваше приложение можно активно использовать при питании от батареи в течение заданного количества часов

Проектирование приложения для повышения производительности

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

Пользовательский интерфейс

  • Максимальное увеличение производительности анализа и загрузки и эффективности памяти для каждой страницы путем оптимизации разметки XAML. Отложите загрузку пользовательского интерфейса и кода до тех пор, пока не потребуется.
  • Для ListView и GridView сделайте все элементы одинакового размера и используйте как можно больше методов оптимизации.
  • Объявите пользовательский интерфейс в разметке, а не создавайте его императивно в коде.
  • Отложите создание элементов пользовательского интерфейса до тех пор, пока пользователь не нуждается в них с помощью атрибута x:Load .
  • Предпочитайте переходы и анимации тем анимациям на основе раскадровки. Анимации на основе раскадровки требуют постоянного обновления экрана и поддерживают активность процессора и графического конвейера.
  • Загружайте изображения в размере, соответствующем тому, как они отображаются.

ЦП, память и питание

  • Планируйте менее приоритетную работу в низкоприоритетных потоках. См. асинхронное программирование и класс DispatcherQueue .
  • Сведите к минимуму потребление памяти приложением, освобождая ресурсоёмкие ресурсы (например, медиаданные), когда они не нужны.
  • Избегайте утечек памяти, по возможности удаляя регистрацию обработчиков событий и ссылки на элементы пользовательского интерфейса.
  • Для экономии заряда батареи сведите к минимуму частоту запросов данных, опроса датчика и планирования задач на процессоре, когда он простаивает.

Доступ к данным

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

Инструмент оценки производительности

По мере написания кода добавляйте в него код, который записывает сообщения и события в журнал в определенных точках во время работы приложения. Позже используйте такие средства профилирования, как Windows Performance Recorder и Windows Анализатор производительности (оба входят в состав Windows Performance Toolkit), для создания и просмотра отчета о производительности вашего приложения.

Windows предоставляет API ведения журнала, поддерживаемые трассировкой событий для Windows (ETW), которые предлагают расширенное решение для ведения журнала событий и трассировки. API в пространстве имён Windows.Foundation.Diagnostics включают классы FileLoggingSession, LoggingActivity, LoggingChannel и LoggingSession.

// using Windows.Foundation.Diagnostics;

LoggingChannel myLoggingChannel = new LoggingChannel("MyLoggingChannel");
myLoggingChannel.LogMessage("Here's my logged message.", LoggingLevel.Information);

Чтобы регистрировать события запуска и остановки в течение определенного периода времени:

LoggingChannel myLoggingChannel = new LoggingChannel("MyLoggingChannel");
LoggingActivity myLoggingActivity;

using (myLoggingActivity = new LoggingActivity("MyLoggingActivity", myLoggingChannel))
{
    // A start event is logged when the activity begins.
    // Add code here to do something of interest.
}
// An end event is logged when the activity ends.

Тестируйте и измеряйте по целевым показателям производительности

Используйте эти методы и инструменты, чтобы проверить, насколько ваше приложение соответствует вашим целевым показателям производительности:

  • Протестируйте различные аппаратные конфигурации, включая настольные компьютеры, ноутбуки, ультрабуки и планшеты.
  • Проверка на широкий спектр размеров экрана. Более широкие экраны показывают больше содержимого, что может негативно повлиять на производительность.
  • Исключите столько переменных тестирования, сколько можно:
    • Отключите фоновые приложения на тестовом устройстве.
    • Создайте приложение в конфигурации выпуска перед развертыванием на тестовом устройстве.
    • Запустите приложение несколько раз, чтобы устранить переменные случайного тестирования и обеспечить согласованные измерения.
  • Проверка снижения доступности питания. Устройства пользователей могут иметь значительно меньше мощности, чем компьютер разработки.
  • Используйте сочетание таких средств, как Visual Studio средства диагностики и Windows Анализатор производительности для измерения производительности приложения.

Реагирование на результаты теста производительности

После анализа результатов теста производительности определите, необходимы ли какие-либо изменения:

  • Следует ли изменить решения по проектированию приложений или оптимизировать код?
  • Следует ли добавлять, удалять или изменять инструментирование в коде?
  • Следует ли пересмотреть цели производительности?

Если изменения необходимы, внесите их и вернитесь к инструментированию или тестированию.

Optimize

Оптимизируйте только пути кода, критически важные для производительности в приложении, — те, где больше всего времени тратится. Профилирование показывает, какие это области. Часто существует компромисс между рекомендациями по проектированию и кодом, выполняющимся при максимальной оптимизации. Приоритет производительности разработчика и хорошего проектирования программного обеспечения в тех областях, где производительность не является проблемой.