Как измерить скорость работы приложения
Для любого мобильного приложения производительность очень важна. Если ваше мобильное приложение не работает должным образом, конечный пользователь удалит ваше приложение и найдет другое приложение, которое работает лучше.
Ваше мобильное приложение должно быть тщательно протестировано перед его выпуском конечному пользователю.
В этом уроке вы узнаете
- Стратегия тестирования мобильных приложений
- Производительность устройства
- Производительность сервера
- Производительность сети
- Устранение неполадок с производительностью мобильных приложений
- Полезные инструменты для тестирования мобильных приложений
- проблемы
- Настройка среды тестирования производительности мобильных приложений
- Контрольный список производительности для мобильных приложений
Стратегия тестирования мобильных приложений
Производительность приложений на мобильном телефоне или любом интеллектуальном устройстве обычно измеряется по следующим трем категориям.
- Производительность устройства
- Производительность сервера / API
- Производительность сети
Производительность устройства
Когда клиент испытывает медленное приложение, он раздражается.
Для производительности устройства, вы будете проверять следующее —
Сколько времени занимает запуск вашего приложения? Это первый параметр производительности, объявленный пользователем. Как правило, после того, как пользователь нажмет на значок приложения, первый экран должен появиться через 1-2 секунды.
On constant use, some mobile apps, consume a high amount of battery life and heat the phone. This factor adds a lot to the performance of any mobile app and could normally happen when your app is using more resources than required. Excessive resource usage creates a burden on the processor and phone gets heat up.
When Testing an app, the memory consumption by an app should be checked. By implementing certain functionalities in the app, the memory consumption also increases. For example, in Android apps when push notifications are implemented then memory consumption increases.
In some cases, it has been observed that memory usage by whole O.S is mere 14%, but a new app is consuming 11%. So, these factors must be handled before deploying the app to the real world or giving to the client.
When testing a mobile app, it is mandatory to check apps on different devices. It could be the case that app is running smoothly on one device but not on other. Like for different vendors of Android devices, we can check the app on Samsung, HTC, and Lenovo phones. Similarly, the app needs to be tested with different RAM and processor specifications like 1 GB or 2 GB.
When the app under test is running in parallel with other apps, there should be no interference. The best way to check it is by switching app under testing and other apps.
An app that is running in the background is retrieved, it should remain in the same state as it was before. If this scenario is not handled properly, then data get lost. Again you have to enter data from scratch upon retrieving the app.
Server/API Performance
When the app is interacting with the server via API, the response time becomes critical to performance. For Server performance, you will check —
The app should handle data efficiently that is sent from the server. It must not take too much time while loading data. In certain apps, data is sent in a specified format. So before displaying it in the app, it should be converted to a relevant format. In this process, apps sometimes become slower and response time becomes longer.
The number of calls from App under test to the server generated from app should be less. In some cases, multiple API calls are made for the same functionality. For better performance, this should be handled with less number of calls.
Due to any reason if the server is down or unreachable we can save data in the native database. So, whenever the server is down, we can show data stored in the native database. Another solution could be the failover database servers i.e. if one of the servers is down or in maintenance phase the backup server should be available to switch over. The failover/backup server should be in continuous replication and synchronization with the main server.
Network Performance
The performance of the app on different networks and network properties need to be measured.
For Network performance, you will check following things.
When there is a delay in receiving information on the network, then it is termed as jitters. It is a problem with the connectionless networks or packet switch networks. As the information is distributed into packets, packets can travel by a dissimilar path from the sender to the receiver. When data arrives at the intended location, it becomes scrambled than it was originally sent. In the case of Jitters, the mobile app should be capable enough to handle it.
You need to Show the appropriate notifications to the end user, either to resend the request or wait till the system responds again.
In the case of complete packet loss, the app should be able to resend the request for the information or should generate the alerts accordingly. If data is not complete, then the user will not be able to comprehend information displayed in App. This can be stressful for the user. So, it is better to display a suitable message or prompt user to try again.
The app needs to be checked on a variety of networks with variable speed. The app should be tested on 2.5G, 3G, and 4G networks. Both Wi-Fi and mobile networks are included in this. Also, the behavior of app should be monitored. Especially, when both networks are available, and switching occurred from one network to another.
Например, проблема может возникнуть в приложении для пользователей при переключении телефонной сети с 4G на WIFI и наоборот. В этом случае приложение перестает отвечать на запросы и может потребовать перезапуска приложения для использования.
Устранение неполадок с производительностью мобильных приложений
Есть одно высказывание: «Что ты не можешь измерить, то ты не можешь улучшить». Автор статьи, перевод которой мы сегодня публикуем, работает в компании Superhuman. Он говорит, что эта компания занимается разработкой самого быстрого в мире почтового клиента. Здесь речь пойдёт о том, что такое «быстро», и о том, как создавать инструменты для измерения производительности невероятно быстрых веб-приложений.
Измерение скорости приложений
Мы, в стремлении улучшить нашу разработку, потратили очень много времени на измерение её скорости. И, как оказалось, метрики производительности — это показатели, которые на удивление сложны для понимания и применения.
С одной стороны — сложно проектировать метрики, которые точно описывают те ощущения, которые пользователь испытывает, работая с системой. С другой стороны — непросто создавать метрики, которые точны настолько, что их анализ позволяет принимать обоснованные решения. В результате многие команды разработчиков не могут доверять собираемым ими данным о производительности их проектов.
Даже если у разработчиков есть достоверные и точные метрики, пользоваться ими нелегко. Как определить понятие «быстро»? Как найти баланс между скоростью и непротиворечивостью? Как научиться оперативно обнаруживать ухудшения производительности или научиться оценивать воздействие оптимизаций на систему?
Здесь мы хотим поделиться некоторыми соображениями, касающимися разработки средств анализа производительности веб-приложений.
1. Использование правильных «часов»
В JavaScript имеются два механизма для получения временных меток: performance.now() и new Date() .
Чем они различаются? Для нас принципиальными являются следующие два различия:
- Метод performance.now() гораздо точнее. Точность конструкции new Date() — ± 1 мс, в то время как точность performance.now() — это уже ± 100 мкс (да, речь идёт именно о микросекундах!).
- Значения, возвращаемые методом performance.now() , всегда возрастают с постоянной скоростью и не зависят от системного времени. Этот метод просто отмеряет промежутки времени, не ориентируясь на системное время. А на new Date() системное время влияет. Если переставить системные часы, то изменится и то, что возвратит new Date () , а это испортит данные мониторинга производительности.
2. Проверка активности приложения
Если вы, измеряя производительность веб-приложения, переключитесь с его вкладки на какую-то другую — это нарушит процесс сбора данных. Почему? Дело в том, что браузер ограничивает приложения, находящиеся в фоновых вкладках.
Имеются две ситуации, в которых метрики могут быть искажены. В результате приложение будет казаться гораздо более медленным, чем на самом деле.
- Компьютер переводится в режим сна.
- Приложение выполняется в фоновой вкладке браузера.
Во-вторых, можно воспользоваться свойством document.hidden и событием visibilitychange. Событие visibilitychange вызывается тогда, когда пользователь переключается с интересующей нас вкладки браузера на другую вкладку или возвращается на интересующую нас вкладку. Оно вызывается тогда, когда окно браузера сворачивается или разворачивается, когда компьютер начинает работу, выходя из режима сна. Другими словами, это именно то, что нам нужно. Кроме того, до тех пор, пока вкладка находится в фоновом режиме, свойство document.hidden равно true .
Вот простой пример, демонстрирующий использование свойства document.hidden и события visibilitychange .
Как видите, некоторые данные мы отбрасываем, но это хорошо. Дело в том, что это данные, относящиеся к тем периодам работы программы, когда она не может полноценно пользоваться ресурсами системы.
Сейчас мы говорили о показателях, которые нас не интересуют. Но существует множество ситуаций, данные, собранные в которых, нам весьма интересны. Посмотрим на то, как собирать эти данные.
3. Поиск показателя, который позволяет наилучшим образом зафиксировать время начала события
Одна из наиболее спорных возможностей JavaScript — это то, что цикл событий этого языка является однопоточным. В некий момент времени способен выполняться лишь один фрагмент кода, выполнение которого не может быть прервано.
Это может сильно исказить метрики. Если нам нужна точность в измерении того, как именно пользователь воспринимает работу с программой, то это — огромная проблема!
К счастью, решить эту проблему не так уж и сложно. Если речь идёт о текущем событии, то мы можем, вместо использования performance.now() (времени, когда мы увидели событие), воспользоваться window.event.timeStamp (время, когда было создано событие).
Временная метка события устанавливается главным процессом браузера. Так как этот процесс не блокируется тогда, когда заблокирован цикл событий JS, event.timeStamp даёт нам гораздо более ценные сведения о том, когда событие было на самом деле запущено.
Тут надо отметить, что и этот механизм не идеален. Так, между моментом, когда нажата физическая кнопка, и моментом, когда соответствующее событие прибывает в Chrome, проходит 9-15 мс неучтённого времени (вот превосходная статья, из которой можно узнать о том, почему это происходит).
Однако даже если мы можем измерить время, необходимое событию на то, чтобы добраться до Chrome, нам не следует включать это время в наши метрики. Почему? Дело в том, что мы не можем внести в код такие оптимизации, которые способны значительно повлиять на подобные задержки. Мы никак не можем их улучшить.
В результате, если говорить о нахождении временной метки начала события, то показатель event.timeStamp выглядит тут наиболее адекватно.
Как лучше всего оценить момент завершения события?
4. Выключение таймера в requestAnimationFrame()
Из особенностей устройства цикла событий в JavaScript вытекает ещё одно следствие: некий код, не имеющий отношения к вашему коду, может выполняться после него, но до того, как браузер отобразит на экране обновлённый вариант страницы.
Рассмотрим, например, React. После выполнения вашего кода React обновляет DOM. Если вы выполняете измерения времени только в вашем коде, это значит, что вы не измерите время, которое ушло на выполнение кода React.
Для того чтобы измерить это дополнительное время, мы, для выключения таймера, используем requestAnimationFrame() . Делается это только тогда, когда браузер готов к выводу очередного кадра.
Вот жизненный цикл кадра (диаграмма взята из этого замечательного материала, посвящённого requestAnimationFrame ).
Жизненный цикл кадра
Как можно видеть на этом рисунке, requestAnimationFrame() вызывается после того, как будет завершена работа процессора, прямо перед выводом кадра на экран. Если мы выключим таймер именно здесь, это значит, что мы можем быть совершенно уверены в том, что в собранные данные о временном промежутке включено всё, что заняло время до обновления экрана.
Пока всё хорошо, но теперь ситуация становится довольно-таки сложной…
5. Игнорирование времени, необходимого на создание макета страницы и её визуализацию
Предыдущая диаграмма, демонстрирующая жизненный цикл кадра, иллюстрирует ещё одну проблему, с которой мы столкнулись. В конце жизненного цикла кадра имеются блоки Layout (формирование макета страницы) и Paint (вывод страницы на экран). Если не учесть время, необходимое на выполнение этих операций, то измеренное нами время будет меньше чем то время, которое нужно для того, чтобы некие обновлённые данные появились бы на экране.
К нашему счастью у requestAnimationFrame есть ещё один туз в рукаве. При вызове функции, переданной requestAnimationFrame , этой функции передаётся отметка времени, указывающая на время начала формирования текущего кадра (то есть — на то, что находится в самой левой части нашей диаграммы). Эта отметка времени обычно находится очень близко к времени окончания предыдущего кадра.
Хотя то, что показано выше, и выглядит как отличное решение проблемы, мы, в итоге, решили этой конструкцией не пользоваться. Дело в том, что, хотя эта методика и позволяет получить более достоверные данные, точность таких данных снижается. Кадры в Chrome формируются с периодичностью 16 мс. Это значит, что наивысшая доступная нам точность составляет ±16 мс. А если браузер перегружен и пропускает кадры, то точность будет ещё ниже, причём это её ухудшение окажется непредсказуемым.
Если вы реализуете это решение, то серьёзное улучшение производительности вашего кода, такое, как ускорение задачи, которая раньше выполнялась 32 мс, до 15 мс, может никак не отразиться на результатах измерения производительности.
Не учитывая время, необходимое на формирование макета страницы и на её вывод, мы получаем гораздо более точные метрики (±100 мкс) для кода, который находится под нашим контролем. В результате мы можем получить числовое выражение любого улучшения, внесённого в этот код.
Мы, кроме того, исследовали похожую идею:
Сюда попадёт время рендеринга, но при этом точность показателя не будет ограничена ±16 мс. Однако мы и этот подход решили не использовать. Если система столкнётся с длительным событием ввода, то вызов того, что передано setTimeout , может быть значительно задержан и выполнен уже после обновления пользовательского интерфейса.
6. Выяснение «процента событий, которые находятся ниже целевого показателя»
Мы, разрабатывая проект и ориентируясь на высокую производительность, пытаемся оптимизировать его по двум направлениям:
- Скорость. Время выполнения самой быстрой задачи должно быть как можно ближе к 0 мс.
- Единообразие. Время выполнения самой медленной задачи должно быть как можно ближе к времени выполнения самой быстрой задачи.
Типичный подход заключается в измерении 90-го перцентиля задержки. Этот подход позволяет нарисовать линейный график, по оси Y которого откладывают время в миллисекундах. Этот график позволяет увидеть, что 90% событий находятся ниже линейного графика, то есть выполняются быстрее, чем за то время, на которое указывает линейный график.
Известно, что 100 мс — это граница между тем, что воспринимается как «быстрое» и «медленное».
Но что мы выясним о том, какие ощущения пользователи испытывают от работы, если будем знать, что 90-й перцентиль задержки равен 103 мс? Не особенно много. Какие показатели обеспечат пользователям удобство работы? Нет способа узнать это наверняка.
А что если мы будем знать о том, что 90-й перцентиль задержки равен 93 мс? Возникает такое ощущение, что 93 — это лучше, чем 103, но ничего больше об этих показателях мы сказать не можем, равно как и о том, что они означают в плане восприятия проекта пользователями. На этот вопрос, опять же, нет точного ответа.
Мы нашли решение этой задачи. Оно заключается в том, чтобы измерять процент событий, время выполнения которых не превышает 100 мс. У такого подхода есть три больших преимущества:
- Метрика ориентирована на пользователей. Она может сообщить нам о том, какой процент времени наше приложение является быстрым, и какой процент пользователей воспринимает его как быстрое.
- Эта метрика позволяет нам вернуть измерениям ту точность, которая была потеряна из-за того, что мы не замеряли время, уходящее на выполнение задач, находящихся в самом конце кадра (мы говорили об этом в разделе №5). Благодаря тому, что мы устанавливаем целевой показатель, который укладывается в несколько кадров, результаты измерений, которые близки к этому показателю, либо оказываются меньше его, либо больше.
- Эту метрику легче вычислять. Достаточно просто посчитать количество событий, время выполнения которых находится ниже целевого показателя, а после этого — разделить их на общее количество событий. Перцентили считать гораздо сложнее. Есть эффективные аппроксимации, но для того чтобы сделать всё правильно, нужно учитывать каждое измерение.
7. Использование нескольких пороговых значений при анализе показателей
Для того чтобы визуализировать результат оптимизации производительности, мы ввели в нашу систему несколько дополнительных пороговых значений — выше 100 мс и ниже.
Мы сгруппировали задержки так:
- Менее 50 мс (быстро).
- От 50 до 100 мс (хорошо).
- От 100 до 1000 мс (медленно).
- Более 1000 мс (ужасно медленно).
То, что укладывается в 50 мс, очень чувствительно к изменениям. Здесь улучшения производительности часто видны задолго до того, как они могли бы быть видны в группе, которой соответствует показатель в 100 мс.
Например, следующий график визуализирует производительность просмотра треда в Superhuman.
Просмотр треда
Здесь показан период падения производительности, а потом — результаты улучшений. Трудно оценить падение производительности в том случае, если смотреть лишь на показатели, соответствующие 100 мс (верхние части синих столбцов). При взгляде же на результаты, укладывающиеся в 50 мс (верхние части зелёных столбцов), проблемы с производительностью видны уже гораздо отчётливее.
Если бы мы использовали традиционный подход к исследованию метрик производительности, то, вероятно, не заметили бы проблему, влияние которой на систему показано на предыдущем рисунке. Но благодаря тому, как мы проводим измерения, и тому, как визуализируем наши метрики, мы смогли очень быстро проблему обнаружить и решить её.
Итоги
Оказалось, что найти правильный подход к работе с метриками производительности на удивление сложно. Нам удалось выработать методику, позволяющую создавать качественные инструменты для измерения производительности веб-приложений. А именно, речь идёт о следующем:
- Время начала события измеряется с помощью event.timeStamp .
- Время окончания события измеряется с помощью performance.now() в коллбэке, передаваемом requestAnimationFrame() .
- Игнорируется всё, что происходит с приложением в то время, когда оно находится на неактивной вкладке браузера.
- Данные агрегируются с использованием показателя, который можно описать как «процент событий, которые находятся ниже целевого показателя».
- Данные визуализируются с выделением нескольких уровней пороговых значений.
Пользователи не любят ждать: если приложения загружается дольше трех секунд, половина из них окажутся разочарованы. Не менее важно, чтобы программа вела себя корректно на разных устройствах и при различной нагрузке. Для этого необходимо тестировать приложение и на стороне клиента, и на стороне сервера. В этой статье мы рассмотрим 10 инструментов тестирования производительности мобильных приложений.
1. Akamai CloudTest
Akamai CloudTest – инструмент нагрузочного тестирования, обеспечивающий проверку производительности с помощью пользовательского тестирования. Пригодится в глобальной оценке нагрузки, моделировании крупных событий, при контроле и создании визуальных тестов.
Особенности:
- есть инструменты непрерывной интеграции, и автоматизированного Shift Left тестирования;
- можно протестировать инфраструктуру с учетом географически распределенной нагрузки, сгенерировать трафик, релевантного фактической пользовательской базе;
- объектно-ориентированные сценарии позволяют вставлять условные выражения и циклы, повторно использовать и комбинировать тесты;
- имеется дашборд для прогона тестовых ситуаций;
- есть готовые панели мониторинга, можно создать и настроить собственные;
- с помощью таких панелей можно объединить аналитику, включив данные из сторонних инструментов мониторинга.
Цена: необходимо уточнять по задаче.
2. Apica LoadTest
Apica LoadTest служит для проверки масштабируемости приложений и определения узких мест в производительности. Поддерживается широкий спектр приложений и устройств: от сайтов электронной коммерции и потокового видео до мобильных приложений и IoT.
Особенности:
- есть стресс-тесты с географической направленностью;
- готовые скрипты для нагрузочного тестирования приложений;
- интегрируется из коробки с New Relic и AppDynamics.
Цена: есть б есплатная пробная версия.
3. Apptim
Apptim позволяет анализировать производительность на стороне клиента. Измеряет время рендеринга, энергопотребление, использование ресурсов, создание журналов и на Android, и на iOS .
Особенности:
- оценивает производительность при запуске на реальных устройствах;
- после каждого сеанса тестирования инструмент генерирует отчет с показателями производительности и ошибками;
- подробная документация;
- когда выходит новая версия приложения, можно сравнить результаты тестов производительности.
Цена: е сть платная и бесплатная версии.
4. BlazeMeter
BlazeMeter предоставляет возможность непрерывного тестирования, а также тестирования производительности под нагрузкой. Есть веб-интерфейсы для создания статических нагрузочных тестов и запуска динамических тестов. Есть распределенное тестирование, отчеты в реальном времени, интеграция с инструментами разработчика и мониторинг производительности приложений.
Особенности:
- cовместимость с Apache JMeter;
- cоздание тестов в любом масштабе – до 1 млн. пользователей;
- настройка тестов в течение нескольких минут;
- запуск из облака или локально;
- запуск тестов из нескольких географических локаций;
- имитация мобильного тестирования с реальных устройств;
- совместное использования сценариев и отчетов;
- интеграция с ведущими инструментами CI и APM;
- мониторинг работы настольных и мобильных пользователей.
Цена: е сть бесплатные, платные и пробные подписки.
5. Eggplant
Eggplant позволяет тестировать любую платформу, приложение или сайт с помощью автоматизированных технологий искусственного интеллекта, машинного обучения и DevOps.
Особенности:
- обеспечивает автоматическое создание пользовательских скриптов, имитирующих действия реальных пользователей;
- позволяет настроить виртуальную аудиторию любым удобным образом.
Цена: е сть бесплатная, платная и пробная подписки.
6. Experitest
Experitest – ведущий поставщиком инструментов для мобильных DevOps: тестирование производительности, нагрузочное и ручное тестирование, мониторинг приложений. Инструменты Experitest поддерживают все мобильные ОС, включая iOS, Android, Windows Phone и Blackberry. Все SaaS- инструменты интегрируются в среды ALM, UFT/QTP, WebDriver/Selenium, Junit, Microsoft Visual Studio.
Особенности:
- интегрирование стандартных автоматизированных тестов Appium и Selenium в CI/CD;
- метрики эффективности и отзывчивости для конечного пользователя в различных сетевых условиях, на разных устройствах, ОС и браузерах;
- подсчет продолжительности транзакции, индекса скорости, использования процессора/памяти/батареи, сетевых данных.
Цена: е сть бесплатные корпоративные планы.
7. Gatling
Gatling – опенсорсная платформа для нагрузочного тестирования и тестирования производительности с акцентом на веб и мобильные приложения. Базируется на Scala, Akka и Netty, интегрируется с инструментами сборки.
Особенности:
Цена: бесплатно.
8. HeadSpin
HeadSpin – глобальная инфраструктура тестирования, использующая машинное обучение.
Особенности:
- постоянный контроль и анализ QoE между приложением, устройством и сторонними интерфейсами;
- расширенные возможности искусственного интеллекта для автоматического определения проблем производительности.
Цена: для уточнения цены необходимо связаться с поставщиком услуг.
9. JMeter
JMeter – опенсорсный Java -софт, предназначенный для анализа и тестирования веб-приложений и различных сервисов при помощи нагрузочного, стресс-, регресс- и функционального тестирования.
Особенности:
Цена: бесплатно.
10. Neoload
Neoload поставляется со всеми возможностями, необходимыми командам для создания реалистичного мобильного нагрузочного тестирования, даже для интернета вещей.
Особенности:
- виртуализация сети для моделирования пропускной способности, задержки и потери пакетов;
- захват времени рендеринга, работы процессора, батареи, памяти;
- прекрасно уживается с Perfecto, Appium, Selenium;
- есть возможность использовать совместно с основными облачными провайдерами, выполняя в одной системе распределенные тесты.
Цена: одна бесплатная пробная версия и две платные.
Если вы хотите улучшить качество мобильного приложения, любой из перечисленных инструментов будет полезен. Прежде чем приступить к тестированию производительности, важно принять во внимание несколько факторов:
Как правило, недостаточно написать инновационное и полезное приложение. Если оно будет зависать, долго запускаться и медленно работать, то все его достоинства будут с лёгкостью перечёркнуты этими недостатками.
Поэтому производительность приложения крайне важна, хотя о ней легко забыть, когда вы делаете дополнительные штрихи к своему UI или придумываете новые интересные функции. Ровно до тех пор, пока не появятся первые негативные отзывы в Google Play.
Пользовательский интерфейс это то, что связывает пользователя с приложением. Сделать его красивым это только половина дела, вы также должны убедиться, что UI отображается быстро и работает плавно.
Например, представьте синий фон с некоторым текстом поверх. Android не просто рисует области синего цвета, которые видны пользователю, он рисует весь синий фон, а затем рисует текст сверху. Это означает, что некоторые пиксели были окрашены два раза, что приводит к избыточности.
Излишние наложения неизбежны, однако их количество при возможности нужно стараться сокращать, поскольку большое количество перерисовок пикселей может привести к уменьшению производительности вашего приложения.
Теперь вы можете зайти в любое приложение, работу которого хотите проверить. Например, посмотрим области наложения в приложении Google Карты.
Не пугайтесь, если увидите, что ваш экран мигает разными цветами. Эти цвета выделяют области, в которых присходит наложение. В зависимости от цвета области определяют, насколько сильное там наложение:
Например, к наложению может привести атрибут background дочернего элемента. Если в качестве его значения выбран белый цвет и цвет родительского элемента тоже указан как белый, то это приведёт к избыточной перерисовке экрана.
Android может сократить количество наложений, однако это распространяется только на простые случаи. Если у вас достаточно сложный интерфейс, система не сможет понять, как вы рисуете свой контент.
Другой распространенной причиной проблем с производительностью является иерархия представлений вашего приложения. При рендере каждого представления, Android проходит три этапа:
- Измерение
- Разметка
- Рисование
Сначала система измеряет элементы представлений. Каждое представление имеет конкретные данные, которые описывают его размер: некоторые имеют определённый размер, другие имеют размер, который адаптирует к размеру родительского контейнера. Затем система расставляет эти элементы представлений, учитывая их размеры, и отрисовывает их на экране устройства.
Время, необходимое для завершения этих операций, будет пропорционально количеству представлений в вашей иерархии. Это означает, что одним из самых простых способов уменьшить время рендеринга картинки является определение и удаление любых представлений, которые не вносят никакого вклада в формирование итогового изображения, которое пользователь видит у себя на экране.
Даже если все представления в вашей иерархии необходимы, упорядочивание этих представлений может существенно повлиять на процесс рендеринга. Вообще говоря, чем глубже ваша иерархия представлений, тем больше времени требуется на формирование итогового изображения.
Во время рендеринга каждое представление предоставляет свои размеры родительскому элементу. Если родитель обнаруживает проблему этими размерами, он заставляет представления их измерить заново. Повторные измерения могут возникать даже при отсутствии ошибки. Например, разметки с RelativeLayout должны измерять свои дочерние элементы дважды, чтобы всё было в порядке. Разметки с LinearLayout, дочерние элементы которого имеют атрибут layout_weight, тоже измеряются дважды.
В зависимости от того, как организованы ваши представления, измерения могут быть дорогостоящей и трудоёмкой операцией, что скажется на времени рендеринга.
Поэтому главной целью здесь является удаление лишний и ненужных представлений в поиске возможности оптимизировать разметку.
Android SDK включает в себя утилиту Hierarchy Viewer, которая позволяет визуализировать всю вашу иерархию представлений. Этот инструмент позволяет определить как избыточные представления, так и вложенные разметки.
Прежде чем начать пользоваться Hierarchy Viewer, нужно учесть, что утилита взаимодействует только с запущенными приложениями, а не с исходным кодом. Поэтому вам нужно сначала установить приложение на устройство или эмулятор.
Cлева вы можете увидеть список подключенных устройств или эмуляторов. Если раскрыть список, в нём отобразятся запущенные процессы. Выберите тот, который в настоящий момент работает и который вы хотите протестировать и дважды кликните на него. Если у вас достаточно сложный интерфейс, утилите потребуется некоторое время на построение иерархии. В результате вы должны увидеть три окна с различными данными.
- Окно Tree View это основное окно, в котором вы можете найти нужный элемент и посмотреть данные о нём.
- Окно Tree Overview представляет собой карту вашей иерархии, по которой можно смотреть, на каком участке вы находитесь.
- Окно Layout View это представление вашей иерархии.
Эти окна связаны между собой, если вы выделите элемент в Tree View, он отобразится в двух других окнах.
Если вы не уверены, действительно ли представление вносит какой-либо вклад в окончательное изображение, просто перейдите в Tree View и щелкните по соответствующему представлению. Вы увидите предварительный просмотр того, как это представление будет отображаться на экране.
Таким образом, анализируя данные, вы сможете увидеть, как представления в вашей иерархии лишние либо работают медленно и требуют оптимизации.
Она позволяет диагностировать утечки памяти, указав, сколько памяти система назначила вашему приложению. Если выделенная память будет расти, то это свидетельствует о том, что ваше приложение имеет утечку памяти.
Этот инструмент также предоставляет множество данных об использовании кучи вашего приложения, в том числе о том, сколько объектов в ней расположено и сколько места они занимают. Эта дополнительная информация может быть неоценимой, если вы отслеживаете источник утечек памяти.
Чтобы получить доступ к Heap, снова запустите Android Device Monitor и выберите вкладку DDMS. На панели Devices выберите устройство и процесс, который вы хотите протестировать, затем нажмите на кнопку над списком Update Heap и выберите вкладку Heap.
Вывод данных о куче отображается только после событий GC, поэтому чтобы заполнять вкладку данными, нужно либо ожидать, когда эти события произойдут, либо нажать Cause GC, чтобы принудительно вызвать событие.
После этого данные об использовании кучи начнут обновляться после каждого нового события либо пока вы взаимодействуете с приложением.
Android Device Monitor, кроме всего прочего, также предоставляет утилиту Systrace. Эта утилита помогает анализировать производительность вашего приложения, захватывая и отображая время выполнения ваших процессов и других системных процессов. Systrace объединяет данные из ядра Android, такие как планировщик процессора, активность диска, и потоки приложений для генерации отчёта в HTML, который показывает общую картинку на момент захвата.
Systrace очень полезен для диагностики проблем отображения, когда приложение медленно загружается либо зависает.
Чтобы воспользоваться этой утилитой, достаточно запустить Android Device Monitor, выбрать нужно устройство и нажать на Capture system wide trace using Andorid systrace.
В открывшемся окне вам предложат выбрать длительность захвата, какой процесс захватить, путь для файла с отчётом, а также данные, которые будут в отчёте. В результате сгенерируется отчёт следующего вида.
Однако здесь очень много лишней информации, поскольку Systrace захватывает все работающие процессы. Нам же в данном случае нужно захватить только процесс с нашим приложением. О том, как это можно сделать, будет написано ниже.
В нашем приложении Менеджер паролей от Wi Fi-сетей используется красивый анимированный плейсхолдер для пустого списка сетей, реализованный в библиотеке desertplaceholder. Исходный код вы можете посмотреть, перейдя по ссылке ранее на GitHub.
Особенность этой библиотеки в том, что в качестве контейнера она использует ConstraintLayout, а отрисовка анимации происходит с помощью Canvas в методе onDraw().
Попробуем слегка переписать код, используя вместо ConstraintLayout RelativeLayout, а вместо onDraw() нативные средства анимации Android, затем посмотрим, изменится ли время загрузки экрана.
Для начала замерим, сколько времени занимает отрисовка в библиотеке. Для этого нам нужно поставить маркеры, по которым Systrace во время захвата определит, что этот участок нужно отобразить в отчёте.
Чтобы это сделать, нужно всего лишь в начале и конце кода, который необходимо замерить, добавить следующий код.
Следует учесть, что использование класса Trace требует в качестве минимальной версии SDK указать minSdkVersion 18.
Таким образом, при следующем захвате мы увидим блок в отчёте с именем SectionName и сможем увидеть длительность его выполнения. В данном случае нам нужно проверить, как быстро рисуется изображение.
Запустим Systrace и сгенерируем отчёт. В результате получился следующий отчет, который можно увидеть на скриншоте ниже.
В отчёте нужный блок легко найти, введя в строку поиска внутри отчёта имя секции. Увеличив блок, мы видим, где начинает загружаться собственно плейсхолдер и замеряем, что длительность выполнения занимает 13,412 мс.
Теперь перейдём к нашему приложению. В нём разметка была слегка изменена и удалены элементы, которые позднее будут анимироваться средствами Android.
Для того, чтобы добавить анимацию, используются классы TranslateAnimation и RotateAnimation. Ниже представлен код добавления анимации для облаков.
Следующий же код показывает добавление анимации для перекати-поле вместе с тенью.
Измерим, сколько времени займёт отрисовка плейсхолдера в нашем приложении и сгенерируем отчёт. В результате получился отчёт следующего вида.
Здесь можно увидеть, что отрисовка плейсхолдера занимает 7,143 мс, а добавление анимации 3,913 мс. Вместе на всё уходит 11,056 мс. То есть изменив способ анимации мы немного, но всё же уменьшили время выполнения кода, добившись аналогичного результата.
В этой статье мы рассмотрели некоторые из наиболее распространённых проблем с производительностью, а также способы их решения.
В Android SDK есть ещё множество средств, которые помогут вам оптимизировать работу приложения. Если вы хотите узнать о них больше, вы можете найти их на сайте официальной документации Android.
Бенчмарки — тесты для производительности устройств — помогут понять, на что способен ваш смартфон в играх и прочих требовательных приложениях. Тесты измеряют скорость и вычислительную мощность центрального и графического процессора, а затем сравнивают результаты с гаджетами других производителей. Мы собрали шесть бенчмарков для разных целей в этом материале.
AnTuTu Benchmark
Показывает подробные сведения о вашем смартфоне и тестирует скорость и мощность процессора и видеоядра — результаты даются в баллах. Но пользователи жалуются, что тест не всегда соответствует действительности
3DMark Benchmark
Бенчмарк с тестами, которые показывают скорость устройства под большой нагрузкой. Еще дает статистику, как менялась скорость смартфона с каждым обновлением ОС
Geekbench 5
Комплексное тестирование производительности во время разных процессов — вроде рендеринга видео и обработки HDR. Есть тесты в одноядерном и многоядерном режимах
PCMark for Android Benchmark
Тестирует расход заряда и памяти устройства. Разряжает телефон до 20%, чтобы проверить производительность с запущенными приложениями в фоне. Бенчмарк критикуют за нестабильную работу
Basemark GPU
Совмещает универсальность AnTuTu и игровую направленность 3DMark. Тесты проводятся в окне с требовательной 3Д-графикой . Из минусов: приложение нестабильное и запрашивает личные данные
Linpack
Тесты, которые при анализе используют алгоритм для измерения скорости суперкомпьютеров. Проверяет, за сколько секунд ваш смартфон решит сложную задачу с большим количеством операций
Больше материалов о гаджетах
В нашем потоке «Технологии». Какие устройства стоит купить и как выжать максимум из вашего телефона и компьютераЦены действительны на момент публикации
Теперь вы знаете, как проверить производительность своего телефона. Осталось узнать:
Мало толку от них. Только для тестирования железа. Но по факту оно может разгоняться под бенчмарк и тормозить в реальных приложениях. И не забываем, что запускать надо раз 10 подряд, чтобы убедиться в отсутствии просадок от перегрева.
Тот же старенький Пиксель или 1+ на старом процессоре может работать отзывчевее и приятнее, чем новый флагманский Сяоми. А дешёвый Виво приятнее среднего Самсунга.
Просто потому, что железо правильно охлаждается, а оболочка и андроид хорошо оптимизированы. И пофиг, что в том же антуту будет отставание в 2-3 раза.
Производители оптимизируют код ОС под бенчмарки. Т.е. при запуске АнТуТу включают буст процессора и т.д. Поэтому проверять лучше на реальных тяжелых приложениях и играх.
Читайте также: