Ускорение
Теперь перейдём к самому вкусному — разберёмся, где можно набрать скорости.
Ускорение старта приложения
Создание процесса. На этом этапе мы мало что можем улучшить. Хотя ребята из Яндекс Браузера рассказали, как они смогли повлиять и на это.
Инициализация Content Provider. В блоке про метрики отдельное внимание было уделено тому, что Application.onCreate() вызывается после ContentProvider.onCreate(). Даже если у вас нет своих контент-провайдеров, возможно они есть у библиотек, которые вы используете.
Например, при подключении FIrebase её не нужно инициализировать в Application.onCreate(), потому что она делает это через Content Provider. Но проблема в том, что это занимает некоторое время. И в это время ничего больше не происходит. А телефоны у нас многоядерные.
Решение очень простое: переопределяем Content Provider FIrebase и выключаем его, если он вам не нужен на старте Application.
<provider
android:name=com.google.firebase.provider.FirebaseInitProvider
android:authorities=${applicationId}.firebaseinitprovider
android:enabled=false
android:exported=false />
А библиотеку инициализируем на старте в фоновом потоке:
FirebaseApp.initializeApp(application)
Только выкидывание Firebase в фон дало нам ускорение около 300 миллисекунд на слабых девайсах.
Не основные процессы. Некоторые библиотеки (у нас это Passport и AppMetrica) работают в собственных процессах. Но класс (не инстанс) Application на всех один. Поэтому в процессе библиотек может проводиться работа, которая там совсем не нужна.
Пример, как определяется процесс и возвращается делегат для выполнения в Application.onCreate():
@NonNull
private ApplicationDelegate delegate() {
if (delegate == null) {
final ApplicationDelegate processDelegate;
switch (MarketProcess.getId()) {
case MAIN:
case ERROR_REPORT:
processDelegate = createMainDelegate(MarketProcess.isInForeground());
break;
case PASSPORT:
processDelegate = new PassportApplicationDelegate(this);
break;
case METRICA:
processDelegate = new MetricaApplicationDelegate(this);
break;
default:
Timber.e(Create stub delegate for unknown process);
processDelegate = new StubApplicationDelegate();
}
delegate = processDelegate;
}
return delegate;
}
Кейс довольно редкий. Далеко не во всех приложениях используются несколько процессов. Но нам это сэкономило сотни миллисекунд на старте приложения.
Инициализация Application. Выносим в фоновые потоки то, что не критично для запуска, чтобы использовать многоядерность. Вынести можно инициализации библиотек (карты к примеру), выполнение каких-то проверок и т.п. Если в Application.onCreate у вас много чего, то пробуйте вынести что-то неважное на фоновый поток.
Выпиливаем SplashActivity
Когда-то давно у нас была Activity, которая после показа сплеш-скрина проверяла наличие Force Update. Она также предлагала выбрать регион и показывала онбординг. Однако запуск Activity не является самой эффективной задачей, поэтому мы перешли к подходу Single Activity и довольны этим решением.
Блокирующий онбординг
Онбординг показывается только один раз во время использования приложения. Зачем проверять необходимость его отображения каждый раз? Правильно – это ненужно. Проверка на старте приложения должна занимать всего лишь миллисекунды.
Несмотря на то, что приложение открыли 100 раз, проверка прохождения онбординга все еще выполняется.
Ускорение экранов
Ускорение создания объектов
Мы используем библиотеку Dagger 2 для управления зависимостями в нашем крупном приложении, где количество классов и, следовательно, создаваемых объектов, очень велико.
Для оптимизации мы применили метод аспектно ориентированного программирования, который позволяет наблюдать за временем, затраченным на инициализацию объекта, и количеством инстансов на каждый класс. Это позволило нам оптимизировать инициализацию объектов, применить правила использования dagger.Lazy, создать Rx-цепочки в фоновом потоке и упростить конструкторы для многих классов.
Создание тяжёлых объектов в фоне
Несмотря на необходимость создания тяжелых объектов, которые не поддаются оптимизации, мы реализовали обёртку, которая выполняет этот процесс в фоновом режиме, не блокируя основной поток.
private val itemsFactoryHeavy = Heavy.initInBackground { itemsFactoryProvider.get() }
private val itemsFactory by lazy { itemsFactoryHeavy.get() }
Кеширование тяжёлых данных
Для критически важных данных, необходимых для запуска приложения, мы используем кеширование в быстром доступе вместо долгосрочного хранилища. Этот подход не только относится к Rx-цепочкам, но и к хранению данных в оперативной памяти, что позволяет улучшить производительность на больших проектах.
Ускорение Presenter
Для ускорения работы презентера, мы используем Moxy. Однако метод onFirstViewAttach вызывается слишком поздно – при вызове onResume у фрагмента. Если у вас сложный интерфейс или тяжелые зависимости, время от onCreate до onResume фрагмента может быть значительным.
Для улучшения этой ситуации, можно попробовать создать контракт, который позволит запустить выполнение операций в презентере раньше вызова onResume у фрагмента.
Советы по оптимизации загрузки экранов в приложении
Тут, как мне кажется, стоит учесть несколько моментов:
Правильный порядок вызова методов
- Не стоит менять реализацию и контракт MVP и вызывать
onAttachпрезентера доonResumeфрагмента; - Стоит придумать метод у презентера, который позволит делать то, что хочется;
- Обратите внимание на жизненный цикл презентера и не забудьте отписаться от загрузки, если презентер уничтожается, так и не вызвав
onAttach.
Оптимизация показа контента
Показ данных с предыдущего экрана:
У нас довольно много информации показывается на сниппетах товаров. При открытии карточки товара данных ещё больше, но можно не дожидаясь запроса, показать то, что у нас было на прошлом экране.
Для быстрого показа карточки товара используем данные с поисковой выдачи. Показ экрана будет мгновенным.
Данные из памяти:
Если есть данные, которые хранятся в виде локального стейта, то можно моментально показать их, а потом актуализировать данными с бекенда. В Маркете, например, список товаров в корзине хранится в памяти. При открытии можно сразу показать его, а потом уже дополнительные данные.
Предзагрузка данных для экрана:
Пока выполняются всякие инициализации, которые нагружают CPU, но не сеть, можно пораньше стартовать запрос данных для экрана, который открывается. Можно использовать это на старте приложения, чтобы ускорить его запуск.
Старт запроса максимально заранее:
При открытии экрана основную часть времени до показа контента занимают сетевые запросы. Лучше стартовать запрос как можно раньше, чтобы контент показался пользователю быстрее и ускорить старт приложения.
Один запрос на экран:
Можно сэкономить много времени, если вместо нескольких запросов сделать один. Это снизит нагрузку на сеть и улучшит эффективность показа контента.
Пагинирование экранов:
Даже если экран не предусматривает пагинацию, лучше использовать RecyclerView и добавлять данные по мере скролла, чтобы избежать долгой загрузки и отрисовки большого ScrollView.
Если найдёте у себя в проекте ScrollView с многочисленными view, рассмотрите возможность рефакторинга.
Лёгкая первая страница
Чтобы максимально быстро показать пользователю контент, можно загрузить минимальное количество данных, необходимое для заполнения экрана. Если экран пагинируется, то вместо 24 больших сниппетов можно загрузить всего 5. Таким образом, пользователь сразу же увидит первую страницу контента, а после этого будет загружать вторую.
Очень простой в реализации способ, который даёт ускорение в десятки процентов от текущих показателей.
Освобождение main thread
Как-то мы заметили, что данные были получены, но при переходе на главный поток проходило какое-то время — у нас около 100 мс. Выяснилось, что main threadбыл загружен и долго не освобождался. Мы оптимизировали его и проблема с задержкой в отображении данных исчезла.
А оптимизировали мы его за счёт следующего пункта.
Ускорение отрисовки
Тут можно посоветовать много и более предметно. Но опишу несколько советов:
- упрощайте сложную вёрстку. На
onMeasureиonLayoutмогут уходить десятки миллисекунд; - переиспользуйте
view holderуRecyclerView; - предсоздавайте
view holderв фоне, пока грузятся данные; - создавайте
viewв фоне с помощью AsyncLayoutInflater.
Асинхронное создание view – это уже сложновато и могут быть баги. Но иногда можно найти неоптимальные места в вёрстке и очень легко поправить. Тем самым ускорив и скорость показа контента и скорость скролла.
Всегда находятся данные, которые не устаревают быстро. В Маркете очень много категорий товаров, но всё же появляются новые не каждый день. Поэтому такие данные можно кешировать. И благо за нас уже это реализовали, остаётся только включить.
Экран будет показываться практически мгновенно. И ещё нагрузка на сеть понизится, за счёт чего другие запросы не будут стоять в очереди.
HTTP ETag
Если у вас есть кеширование запросов, то можно настроить технологию, которая позволит сэкономить на отправке данных с бэкенда и парсинге ответа. Она работает так:
- При первом запросе сервер отдаёт ответ и идентификатор этого ответа.
- Вы кешируете ответ и идентификатор.
- При следующем таком же запросе посылаете идентификатор.
- Если ответ такой же, то сервер не возвращает ответ, а присылает код 304, который говорит, что данные не изменились, используйте свой кеш.
Если ваш бекенд поддерживает эту технологию и у вас есть кеш, то обязательно попробуйте. Включить не сложно, а сэкономит сотни миллисекунд (особенно на медленном интернете).
Предзагрузка на старте приложения
До этого я рекомендовал выкидывать из начала всё, чтобы главный экран показывался быстрее. Но как только он отображается, можно использовать свободное время для предварительной загрузки данных, которые, скорее всего, понадобятся пользователю.
В Маркете мы так подгружали первую страницу каталога. Так как это довольно популярный экран. За счёт этого экран открывался и показывал контент моментально.
Моментальная реакция на действие. Иногда можно не крутить анимацию ожидания после нажатия пользователя на кнопку, а сразу показать, что действие выполнено. В фоне можно отправить запрос. Если всё прошло успешно, то пользовательский интерфейс не изменится. Но в случае отсутствия сети или ошибки произойдёт откат UI в исходное состояние и будет показана ошибка.
В Маркете так работает кнопка добавления товара в корзину. Реализация не сложная, а эффект очень заметный.
Очистите кэш приложений
Кэш приложений – это временные файлы, которые используются для ускорения работы приложения. Однако, со временем, они занимают все больше места в памяти устройства и замедлять его работу.
Для очистки данных нужно найти в "Настройках" необходимое приложение, выбрать в меню "О приложении"/"Использование памяти", а затем – "Удалить данные" либо "Очистить кэш".
Как платформы без кода, такие как AppMaster, могут помочь в оптимизации производительности приложений?
Платформы такие как могут упростить разработку приложений, позволяя разработчикам сосредоточиться на оптимизации производительности приложений, а не на написании сложного кода. Они часто предлагают функции, которые помогают оптимизировать дизайн пользовательского интерфейса и интеграцию с серверной частью, способствуя повышению производительности приложений.
Кратко о том, как повысить производительность ноутбука
Перечислим, что можно сделать, чтобы компьютер работал шустрее:
Установить последние обновления операционной системы;
Провести полное сканирование дисков встроенным защитником Windows и сторонним антивирусным ПО;
Очистить систему охлаждения от пыли;
В настройках электропитания выставить режим высокой производительности;
Удалить все ненужные программы, службы, почистить список автозагрузки;
Поменять HDD на SSD;
Добавить оперативки;
Разгон «железа» использовать только если вы очень опытный пользователь.
Настройка электропитания
Требования экономии и экологии и тот факт, что комп не часто работает на пределе, побуждают производителей вводить режимы ограниченного электропотребления. Для ноутбуков это особенно важно, потому что пользователи хотят экономить заряд аккумулятора.
В результате система работает медленнее просто потому, что ей не хватает энергии. Если эффективность работы для вас важнее — самое время зайти в «Параметры», открыть «Настройки питания» и выбрать максимальную производительность.
Только учтите, что после этого аккумулятор будет садиться быстрее, и за его зарядом придётся следить.
Способ № 8. Почистите компьютер от пыли
Во время работы комплектующие компьютера, бывает, перегреваются, и из-за этого падает его общая работоспособность. Причина в том, что его давно не обслуживали. И теперь охлаждающая система не справляется со своей задачей.
Чтобы исправить это, нужно почистить ПК. Вы можете сделать это сами в домашних условиях, но только в том случае, если умеете делать это. Лучше не пробовать, если не готовы к рискам случайно повредить хрупкие элементы компьютера. Например, шлейфы, которые крепятся к материнской плате.
Чтобы не рисковать, лучше пригласите специалиста или обратитесь в сервисный центр. Там компьютер вскроют, очистят от пыли и заменят термопасту.
Лучше не дожидаться, когда компьютер начнёт шуметь и перегреваться от пыли внутри. Советуем делать профилактическую чистку раз в год.
Это самый радикальный способ повысить производительность компьютера. Чтобы выбрать подход и понять, что именно стоит заменить, ориентируйтесь на вашу проблему. Вы можете:
установить дополнительную планку ОЗУ;
заменить жёсткий диск на более вместительный, если в старом не хватает памяти или он начинает приходить в негодность;
поменять видеокарту на более мощную, если вас беспокоят фризы и вылеты в играх.
Своевременно менять комплектующие — это не прихоть, а необходимость. Любая техника со временем выходит из строя, это нормально. А программы, между тем, становятся всё более требовательны к характеристикам компьютера.
Если производительность важна для вас, советуем актуализировать вашу сборку примерно раз в 4–5 лет.

Способ № 5. Отключите дополнительные эффекты
Есть ещё один секрет, как повысить производительность ПК, — отключить всю бесполезную красоту. В Windows 10 вложены визуальные эффекты, которые тоже влияют на работу компьютера. И если убрать их, это поможет ему работать быстрее.
Чтобы сделать это, снова зайдите в Параметры, а затем — в Специальные возможности. Прокрутите раздел Дисплей до конца, пока не увидите заголовок Упрощение и персонализация Windows. Здесь можно отключить визуальные эффекты — анимацию и прозрачность.

Как я могу оптимизировать использование памяти в своем приложении?
Вы можете оптимизировать использование памяти, используя эффективные структуры данных, освобождая неиспользуемые ресурсы, реализуя правильную сборку мусора и избегая утечек памяти.
Как выявить проблемы с производительностью приложения для Android?
Вы можете выявить проблемы с производительностью с помощью инструментов профилирования, мониторинга использования ресурсов и проведения пользовательского тестирования. Такие инструменты, как Android Profiler и сторонние службы мониторинга, могут оказаться ценными.
Способ № 4. Установите обновления ОС
Чтобы ПК работал как следует, важно следить за последними обновлениями операционной системы. С ними разработчики исправляют ошибки предыдущих версий и добавляют новые решения, чтобы улучшить ваш опыт.
По умолчанию компьютер получает обновления автоматически во время перезагрузки или перед тем, как завершить работу. При этом система предупредит вас о том, что будет обновление, — через сообщение или кнопки в меню Пуск. Но если раньше вы отключили автообновления, следить за их выходом придётся самому.
Чтобы проверить, нет ли свежих обновлений, перейдите в Параметры и найдите вкладку Обновление и безопасность. Первым откроется нужный нам раздел — Центр обновления Windows 10. Здесь вы можете увидеть, нужно ли установить свежую версию ОС, а ещё настроить время обновлений и посмотреть их историю.

Если вы установили свежее обновление и заметили, что после этого ваш компьютер потерял в производительности, можно откатить систему до предыдущего. Не все обновления стабильны, и разработчикам бывает нужно время, чтобы исправить ошибки. Подождите выхода следующего пакета и обновите систему снова.
Способ № 1. Удалите из системы весь мусор
Это самый простой способ. Со временем система «забивается» данными, которые компьютер никак не использует. И именно они могут тормозить его работу. Речь о временных файлах, загрузках, кеше и т. д. Чтобы вернуть компьютеру работоспособность, попробуйте удалить их. И на будущее запомните: это стоит делать регулярно.

Здесь вы найдёте информацию о ваших дисках и их содержимом. Если хотите удалить временные файлы, кликните на нужную строку. Система сама проанализирует данные на дисках и предложит удалить всё, что бесполезно. Кроме самих временных файлов, это могут быть:
- данные прошлых обновлений системы и прочее.
Если вы не готовы расставаться с чем-то из этого, просто снимите галочку напротив нужного варианта. А затем нажмите Удалить файлы сверху. Вы удивитесь, как сильно это ускорит работу вашего ПК.

Советуем обратить внимание на функцию контроля памяти в Windows 10. На первом скрине в этом материале видно, что она поможет вам следить за тем, чтобы временные файлы не «забивали» память. Если включить её, система будет удалять ненужные данные. Это полезно.
Также для чистки ПК от мусора есть много полезных программ. Их задача — постоянно анализировать состояние вашего компьютера и искать в нём временные файлы, забытые документы и программы, которые вы не используете.
В таблице ниже расскажем о самых любимых из них. Попробуйте — они подскажут, как ускорить работу компьютера здесь и сейчас.
| Полезный софт для чистки ПК | |
| —————————————————————————————————————————————————————————————————————————————————————————— | —————————– |
| | | |
| | Самая популярная программа для очистки ПК. Умеет находить дубли файлов, временные файлы и другой мусор на диске. Анализирует работу приложений и подсказывает, как оптимизировать работу ПК. Большая часть функций доступна бесплатно, но есть и платная улучшенная версия. | От 1 240 рублей за PRO-версию |
| | Полезная утилита, которая помогает вычищать из компьютера файлы, что остались в нём после удаления программ. Базовыми функциями можно пользоваться бесплатно. | От 2 027 рублей за PRO-версию |
| | Хорошая программа для очистки с большим арсеналом средств. Работает на базе искусственного интеллекта. Есть дружелюбный для обычных пользователей интерфейс, все функции в быстром доступе. | От 990 рублей за PRO-версию |
| | Программа с самым большим набором функций в этой подборке. Есть возможность удалять ненужные программы и гибко настраивать очистку. Приложение условно-бесплатное, но за большинство полезных функций вас платить не заставят. | От 2 396 рублей за PRO-версию |

Способ № 6. Проверьте систему на вирусы
Вредоносное ПО — один из главных факторов, который влияет на производительность компьютера. Вирусы, черви, шпионские и майнинговые программы прожорливы до памяти, и это не самая большая их опасность. Чтобы уберечь компьютер и ваши персональные данные, регулярно проверяйте ПК на угрозы и удаляйте подозрительные файлы. В этом вам помогут антивирусы.
Обратите внимание: антивирусы не сами по себе улучшают производительность. Наоборот, они нагружают компьютер во время проверок. Но их работа — не давать вирусам влиять на компьютер, поэтому они так важны.
| Лучшие антивирусные программы для ПК | | |
| —————————————————————————————————————————————————————————————————————————————— | ——————————————————————————————————————————————————————————————————————– | ————————————————– |
| | | | |
| | Это встроенный в ОС антивирус, который прекрасно справляется со своими задачами. Он не перегружает систему, хорошо ловит червей и вирусы, даёт регулярные отчёты о проверках. То, что нужно для домашних компьютеров. | | |
| Kaspersky Internet Security | Самый известный антивирус в России, который часто берёт первые места в топах лучших. Имеет встроенный брандмауэр, контролирует безопасность платежей, позволяет делать резервные копии и ещё многое всего полезного. | Kaspersky Internet Security — от 1 709 рублей/год. |
| | Ещё один отечественный антивирус с большим количеством хороших отзывов. Бережно относится к данным пользователя, хорошо защищает от интернет-угроз и взлома. Есть комплексная защита для нескольких устройств сразу, включая смартфоны. | Есть бесплатная демоверсия и тест-драйв программы на 2 месяца за 300 рублей. Dr.Web KATANA — 1 000 рублей/год Dr.Web Security Space — 1 290 рублей/год | |
Лечить компьютер от вирусов — это хорошо и нужно, но лучше всего вообще не допускать заражения. Для этого следуйте правилам безопасности:
не переходите на подозрительные сайты без SSL-сертификата;
не открывайте сомнительные письма;
не запускайте приложения и не открывайте файлы, которые скачали из небезопасных источников;
не переходите по ссылкам внутри странных сообщений.
И пользуйтесь антивирусом, конечно.

Способ № 2. Отключите автозагрузки
Есть программы, которые по умолчанию запускаются в момент, когда вы включаете компьютер. А дальше — продолжают работать в фоновом режиме, пока вы заняты другими делами. И тем самым влияют на скорость работы ПК: нагружают его дополнительными процессами и «забивают» оперативку.
Чтобы увеличить производительность ПК, советуем отключить автозагрузку для как можно большего количества программ. Или хотя бы для тех, которые вы не используете каждый день. Показываем, как это сделать в Windows 10:
Откройте Диспетчер задач.
Найдите вверху вкладку Автозагрузка и перейдите в неё.
Проверьте статус автозагрузки для приложений в списке.
Отключите автозагрузку, желательно для всех приложений. Либо оставьте только те, с которыми вы точно будете работать после включения ПК.


Метрики
Чтобы что-то ускорять, это что-то нужно замерить. Важные моменты по метрике:
Замеры с точки зрения пользователя. Не нужно замерять время открытия экрана с момента, когда у роутера вызвался какой-то метод. Нужно начинать замер, как только юзер нажал на кнопку перехода к экрану. Мы же замеряем не скорость кода, а скорость предоставления фичи пользователю.
Замеры только конкретный узкий сценарий. Нужно выкидывать замеры открытия экрана, если:
показалась ошибка или
empty state;показался блокирующий попап, который стоит на пути показа контента экрана;
при открытии экрана пользователь свернул приложение, ушёл с экрана;
приложения открывается по диплинкам или пуш-уведомлениям.
Если посылать все сценарии в одну копилку, то метрики будут недостоверными. Например, сообщение об ошибке отобразится быстрее, чем контент.
Замерять можно разное время. Здесь я имею в виду разные состояния приложения. Показали хоть что-то — отправили метрику. Показали большое количество контента — отправили метрику. Показали весь контент — снова отправили метрику. Дали пользователю возможность не только смотреть, но и кликнуть — вы уже знаете, что делать.
В процессе ускорений можно придумывать хаки и показывать часть данных как можно скорее. Но при этом нужно замерять, когда пользователь получит все данные и когда сможет с ними взаимодействовать.
Детализируйте метрику. Отправляйте не только метрику, сколько открывался экран, но и из каких этапов состояло открытие и сколько эти этапы длились. Это нужно, чтобы можно было легко понять, от ускорения каких частей приложения будет больше эффекта.
Небольшая ремарка: я рассматриваю старт приложения, как отдельный кейс, потому что в процессе происходит намного больше событий в отличие от простого открытия экрана.
Замер старта приложения
На схеме отражены основные этапы, которые проходит приложение при старте на примере приложения Яндекс Маркета.
Так стартует Яндекс Маркет
Давайте рассмотрим некоторые этапы детальнее:
Создание процесса. От клика пользователя на иконку и до вызова onCreateу основного инстанса Application. Почему основного? Потому что могут быть другие инстансы Application в других процессах. Получить время, потраченное на создание процесса, можно через вызов метода:
public class MarketApplication extends Application {
@Override
public void onCreate() {
Long processCreationDuration = SystemClock.elapsedRealtime();
super.onCreate();
...
// Фу, Java. Понимаю. Но переписывать на Kotlin этот класс никто не захотел. И правильно.
}
}
Важно зафиксировать время как можно раньше. То есть до вызова super.onCreate(). Можно в статическую переменную записать. Это ещё раньше вызова onCreate.
По поводу метода снятия времени есть неплохая серия статей о времени старте приложения.
Инициализация Content Provider. Если в приложении задекларирован ContentProvider, то он инициализируется до вызова onCreateу Application. Некоторые библиотеки используют этот хак, чтобы проводить необходимые им работы на старте, чтобы не утруждать разработчика — например, Firebase_._
Инициализация Application. Здесь я говорю о промежутке от вызова onCreate у основного инстанса Application до вызова метода onCreate у основной Activity. Тут выполняется написанный нами код, чтобы что-то сделать на старте. Библиотеки чаще всего инициализируются тут.
Создание Activity. Это создание Activity системой, а также super.onCreate.
Инициализация зависимостей Activity. В блоке onCreate начинаем создавать всё, что нам нужно для работы Activity и дальнейших шагов.
Создание табов и других элементов. Тут создаются табы, добавляются корневые фрагменты, проверяются онбординги — всё то, что считается важным для показа до главного экрана.
Открытие главного экрана. Здесь сосредоточены все те работы, которые присутствуют при открытии любого другого экрана. Об этом дальше.
Мы уже поняли, что нам нужно замерять конкретный сценарий. Если мы замеряем холодный старт (запуск при мёртвом процессе), то нужно игнорировать другие сценарии. Ведь приложение может запускаться не только по клику по иконке, а ещё из пуша, через диплинк, из недавних приложений, при вызове BroadcastReceiver, Service, ContentProvider. А ещё в процессе открытия (пока метрика считается, но не отправилась) приложение могут свернуть, выйти из него и снова зайти, заблокировать телефон, быстро открыть другой экран, пока главный не показался.
Пара примеров, как эти кейсы влияют на метрики:
Как метрика тикает, пока пользователь не нажмёт на пуш или не откроет приложение. Так происходит из-за того, что процесс жив
Как метрика тикает, пока пользователь свернул приложение. А когда развернёт, то отправится огромная цифра
Довольно сложно отловить все эти сценарии. Нам помогла стейт-машина.
При различных событиях меняется стейт. А разные стейты и метрику шлют по-разному.
class PushService: FirebaseMessagingService {
override fun onMessageReceived(message: RemoteMessage) {
state.onPushReceived()
// При получении пуш-уведомления стейт поменяется на PushReceivedState
}
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
state.onUiHidden()
// При сворачивании приложения стейт поменяется на UiHiddenState
}
}
По умолчанию при Application.onCreate стейт устанавливается в ColdStartState. В свою очередь, он меняется на HotStartState при таких событиях:
Когда показываем онбординг. Метрика открытия будет неверной, так как это не чистое открытие главного экрана.
Когда открываемся по диплинку. Метрика открытия будет неверной, так как не ждём показа главного экрана, а сразу открываем другой экран.
Когда отправили метрику. Переключаемся в стейт горячего запуска. При живом процессе, все запуски горячие.
class ColdStartState: BaseState {
override fun onUiHidden(): BaseStartAppState {
cancelAllEvents()
// отменяем отправку всех событий, так как они будут нерепрезентативными
return UiHiddenState(this)
}
override fun onMainScreenShowed(): BaseStartAppState {
sendMainScreenOpenedMetrica()
// отправляем метрику скорости открытия главного экрана
return HotStartState(this)
// пока процесс жив, то дальнейшие открытия главной будут считаться горячим запуском
}
}
class UiHiddenState: BaseState {
override fun onUiHidden(): BaseStartAppState {
return this // ничего предпринимать не нужно. Мы уже в данном состоянии
}
override fun onMainScreenShowed(): BaseStartAppState {
// не отправляем метрику скорости открытия главного экрана,
// так как открытие прерывали, свернув приложение
return HotStartState(this)
// пока процесс жив, то дальнейшие открытия главной будут считаться горячим запуском
}
}
Замер скорости открытия экрана
Открытие экранов замерять намного проще в отличие от старта приложения.
Основные этапы открытия экрана в приложении Маркета
Код замеров
В случае Маркета можно выделить следующие сущности:
Router— класс навигации. Знает, что за экран открыт сейчас и как открыть другой.SpeedService— синглтон класс, который хранит и отправляет метрики скорости.MetricaSender— класс, отвечающий за отправку метрик с конкретного экрана. А ещё он нужен для того, чтобы легко из любого места в коде можно было отправить детальную метрику к экрану. Например, сколько выполнялся запрос за данными на уровне обёртки для сетевого слоя.
Помните, в начале статьи мы подчеркнули, что стартовать замер нужно при взаимодействии пользователя? Иногда проще в навигацию положить код. Но если у вас есть явные сценарии, когда до навигации что-то происходит, то лучше стартовать метрику руками (не в коде навигации).
Для чего нужны эти сущности:
Завершить замер. MetricaSender конфигурируется контекстом экрана. Разработчик просто вызывает метод, когда хочет завершить замер. MetricaSenderс информацией об экране идёт в SpeedService, берёт время начала открытия для экрана и фиксирует текущее время — metricaSender.finishScreenOpening().
Также можно отправить дополнительную информацию: холодное открытие экрана, параметры экрана, количество элементов на экране. А ещё можно вызвать метод, передав туда время завершения метрики. Тогда для завершения будет использоваться именно оно, а не браться текущее.
Отменить замер. MetricaSender говорит SpeedService, что нужно удалить время старта метрики для данного экрана — metricaSender.cancelScreenOpening().
Разгон
Современную технику производитель редко заставляет работать на пределе, и ноутбуки здесь не исключение. Технически процессоры, ОЗУ, видеокарты способны работать на более высоких частотах, чем установлены по умолчанию, а значит — это тоже вариант, как улучшить производительность ноутбука.
Разогнать ноутбук — рекомендуемая опция для опытных пользователей, особенно геймеров, но это требует знаний и осторожности, потому что иначе можно повредить компоненты и снизить срок их службы.
Как разогнать процессор
Ускорение CPU чаще всего делают через BIOS либо специальной утилитой SetFSB. В первом случае заходим в BIOS, потом в настройки CPU и ищем CPU Host Clock Controller. Здесь мы аккуратно, не более 5% за раз, увеличиваем частоту процессора, после чего тестируем на стабильность работы и перегрев. После этого общий прирост, скорее всего, составит 15—20%.
Для разгона через SetFSB вам потребуется знать PLL чипа материнской платы. Его можно найти на сайте производителя или посмотреть на самой плате. Далее запускаем SetFSB, в окне Clock Generator выставляем PLL, жмем кнопку Get FSB и понемногу сдвигаем ползунок вправо.
Как разогнать оперативку
Если покупка новой планки ОЗУ вам по каким-то причинам не подходит, можно улучшить работу имеющейся. Начинающим пользователям выполнять разгон стоит через XMP-профили. В них тактовые частоты и тайминги платы уже подобраны специалистами, вам останется только выставить нужный вариант.
Находятся XMP-профили в BIOS, в зависимости от модели ноутбука это может быть Extreme Tweaker, DRAM Setting, M.I.T. или что-то еще. Как и в случае разгона CPU, выставлять новые профили с повышенной производительностью нужно пошагово и каждый раз тестировать ноут на стабильную работу.
Как разогнать видеокарту
Начинающим проще разобраться, как сделать разгон GPU, ведь ПО для этого создают сами производители видеокарт. Так, для NVIDIA есть утилита Inspector. Нужно лишь запустить ее, нажать кнопку Show Overclocking и потихоньку повышать параметры работы карты.
А для AMD имеется встроенный инструмент Catalyst Control Center. Запускаем его, переходим в раздел «Игры» — «Производительность в играх» и начинаем понемногу улучшать настройки.
Главный нюанс в разгоне видеокарт — внимательно следить за нагревом, и если он достигает критических уровней, сделать шаг назад.
Проверка на вирусы
Когда компьютер не такой уж и старый, и «тормоза» начинаются неожиданно — сразу же возникает подозрение на зловредное ПО. Если ваш ноутбук раньше не лагал, а тут вдруг внезапно стал работать хуже — стоит проверить его на присутствие чужих программ.
Начать можно со встроенного защитника от Microsoft. Он называется Defender. Это вполне добротный антивирус, который способен обнаружить и удалить большинство компьютерных угроз.
Нажмите клавишу Windows на клавиатуре или щелкните на значке «Пуск»;
Дальше «Настройки» (иконка шестеренки);
Выберите «Обновление и безопасность»;
Теперь «Безопасность Windows» из левой боковой панели;
Откройте Windows Security;
Выберите «Защита от вирусов и угроз»;
Здесь вы должны увидеть раздел «Параметры сканирования». В этом разделе можно выбрать один из четырех вариантов сканирования:
Быстрое;
Полное;
Настраиваемое;
Проверка автономным модулем Microsoft Defender.
Выбирайте второй вариант, если у вас есть достаточно времени и вы хотите быть уверены, что весь компьютер проверен, либо выберите четвертый, если времени не так много.
Помимо проверки защитником стоит пройтись по другим пунктам — Защита учетных записей, Брандмауэр и т.д. Везде должны быть зеленые галочки, если где-то желтая или красная — принимаем рекомендуемые меры.
Дополнительно стоит проверить ноут как минимум одной из антивирусных утилит, вроде Kaspersky Virus Removal Tool или Dr.Web CureIt! — они бесплатны и не требуют установки.
Если обнаружились посторонние программы, после их удаления лучше усилить защиту. Выбор антивирусного ПО — отдельная тема, однако рекомендуем того разработчика, чья утилита обнаружила зловред. Главное помните, что на компьютере должен быть лишь один антивирус, потому что между собой они конфликтуют. Также после установки нового антивируса убедитесь, что Microsoft Defender теперь выключен.
Отключите сервисы Google
На практике довольно большое количество сервисов Google просто занимает память и почти не используется. К примеру, это Google "Ассистент", который на старых устройствах начинает тормозить, поэтому рекомендуется отключить эту функцию через настройки аккаунта Google.
Также стоит обратить внимание на другие приложения, которые могут замедлять работу устройства и занимать память, такие как цифровая клавиатура, виджет поиска и голосовой ввод.
Полезные инструменты для мониторинга производительности и отладки
Эффективный мониторинг производительности и регулярная отладка необходимы для поддержания и оптимизации производительности приложений Android. Вот список некоторых полезных инструментов, которые помогут вам отслеживать, анализировать и отлаживать различные аспекты вашего приложения:
Профилировщик Android Studio
Profiler — это набор инструментов, позволяющий оценить производительность вашего приложения непосредственно в среде разработки. Он предоставляет информацию об использовании ЦП, распределении памяти, энергопотреблении и сетевых операциях. Эти аналитические данные позволяют выявлять и устранять узкие места производительности, одновременно оптимизируя использование ресурсов на нескольких уровнях.
Мост отладки Android (ADB)
Android Debug Bridge — это универсальный инструмент командной строки, который обеспечивает связь между вашим компьютером разработки и устройством или эмулятором Android. С помощью ADB вы можете управлять установкой, удалением и отладкой приложений, а также получать доступ к подробным журналам и информации об устройстве. ADB может иметь решающее значение для выявления проблем в вашем приложении или системе.
УтечкаКанарейка
LeakCanary — это библиотека обнаружения утечек памяти с открытым исходным кодом для приложений Android и Java. Это может помочь вам выявить и устранить утечки памяти в вашем приложении Android, улучшая стабильность приложения и удобство использования. LeakCanary легко интегрируется, что значительно сокращает время и усилия, необходимые для мониторинга и устранения проблем с утечками памяти.
Ворс
Lint — это важный инструмент статического анализа кода в , который отслеживает вашу кодовую базу на предмет потенциальных уязвимостей, проблем с производительностью и нарушений стандартов кодирования. Lint помогает улучшить качество кода, выявляя проблемы на ранних этапах процесса разработки, что приводит к меньшему количеству сбоев во время выполнения и повышению стабильности приложения.
Сетевой профилировщик
Сетевой профилировщик полезен для измерения использования сети вашим приложением и понимания того, как оно взаимодействует с веб-сервисами. Это позволяет разработчикам выявлять ненужные или избыточные сетевые запросы, оптимизировать поток запросов/ответов и управлять использованием полосы пропускания приложения. Правильное управление сетью имеет важное значение для обеспечения более плавного взаимодействия с пользователем, особенно в плохих условиях сети.
Шаблоны проектирования для повышения производительности приложений Android
Принятие правильных шаблонов проектирования на ранних стадиях жизненного цикла разработки вашего приложения может повысить его производительность и удобство сопровождения. Вот несколько ключевых шаблонов проектирования, которые могут повысить производительность ваших приложений для Android:
Попробуйте no-code платформу AppMaster
AppMaster поможет создать любое веб, мобильное или серверное приложение в 10 раз быстрее и 3 раза дешевле
Шаблон ViewHolder для RecyclerView
Шаблон ViewHolder — это метод оптимизации производительности, который повышает производительность Android RecyclerView за счет сокращения количества создания и повторного использования представлений. Используя шаблон ViewHolder, вы можете минимизировать количество вызовов findViewById() , который, как известно, является дорогостоящим, предотвращая избыточное раздувание представлений и ускоряя прокрутку. Более того, этот шаблон упрощает читаемость и удобство обслуживания кода.
Стратегии кэширования
Кэширование может значительно сократить количество сетевых запросов, которые делает ваше приложение, помогая повысить производительность приложения. Следование правильным стратегиям кэширования снижает зависимость приложения от доступности сети и ускоряет извлечение данных. Могут использоваться различные механизмы кэширования, включая кэширование в памяти, на диске и на сервере. Используйте соответствующие политики вытеснения из кэша, такие как «Наименее недавно использованные» (LRU) и «Первым пришел — первым обслужен» (FIFO), чтобы сохранять наиболее важные данные в кэше.
Ленивая загрузка изображений
Отложенная загрузка изображений помогает экономить пропускную способность и повысить производительность приложения, загружая изображения только тогда, когда они становятся видимыми пользователю. Этот метод экономит ресурсы и обеспечивает более плавную прокрутку списков с многочисленными изображениями. Библиотеки Android Glide и Picasso — популярный выбор для реализации отложенной загрузки.
Шаблон Модель-Представление-ViewModel (MVVM)
Применение архитектурного шаблона MVVM улучшает отделение логики пользовательского интерфейса приложения от бизнес-логики и модели, что приводит к повышению удобства сопровождения, производительности и читаемости кода. MVVM удобно разделяет управление данными и пользовательским интерфейсом, что упрощает обработку сложных сценариев использования пользовательского интерфейса, модульное тестирование и масштабирование приложений. Компоненты архитектуры Android, такие как LiveData, ViewModel и Room, легко интегрируются с шаблоном MVVM.
Инструменты
Timeline
Когда есть большой и длительный процесс (например, запуск приложения), в котором участвует много составляющих, хочется понять, как они взаимосвязаны и каким образом они влияют на длительность процесса. Так можно обнаружить пустые промежутки во времени, на которые необъяснимо зачем потрачено время.
Чтобы построить такую временную шкалу, наш разработчик написал библиотеку Timeline. С помощью удобного API она позволяет собирать, фильтровать, преобразовывать временные интервалы, шарить собранные данные и строить временную шкалу на их основе.
Пример таймлайна из README
Мы используем этот инструмент не только для профилирования, но и для того, чтобы сотрудники, у которых есть к debug-меню, могли просмотреть информацию и отправить разработчику данные о своём случае при использовании приложения, чтобы понять, почему открытие экрана занимает так много времени.
Chrono
Помимо Timeline наш талантливый разработчик реализовал ещё одну очень полезную при профилировании библиотеку Chrono. В лог автоматически пишется ссылка на код, который замерялся.
Также можно замерять не только участок кода, но и расставлять точки для измерения, чтобы увидеть, как долго выполняется каждая часть.
Профайлер
Ну и конечно, никак не обойтись без стандартного профайлера из Android Studio. Профайлер хоть и долго работает, зато детально показывает участки кода, которые отнимают больше всего времени.
В этой статье я старался донести не код, а скорее свой опыт и подходы, которые наша команда попробовала для ускорения. В итоге мы пришли к выводу, что самым жирным местом для ускорения остались сетевые запросы. При этом на старте у нас их было очень много. Так мы стали делать один запрос в бэкенд, который вернёт не кучу данных, которые нужно ещё провести через бизнес логику, а сразу готовые данные для отрисовки. Так мы пришли к BDUI и собственному мобильному бекенду.
Ключевые показатели эффективности
Чтобы оптимизировать производительность вашего Android-приложения, вам необходимо сначала определить и проанализировать важные ключевые показатели эффективности. Эти ключевые показатели эффективности помогут вам сосредоточиться на областях, требующих улучшения, и позволят вам измерить влияние реализуемых вами оптимизаций. Некоторые ключевые показатели эффективности включают в себя:
Время загрузки приложения. Время, необходимое для загрузки вашего приложения, влияет на удовлетворенность пользователей. Медленная загрузка может привести к увеличению количества отказов пользователей. Старайтесь, чтобы время загрузки приложения не превышало 2–3 секунд.
Использование энергии. Чрезмерное потребление энергии может привести к разрядке устройств ваших пользователей, что приведет к негативным впечатлениям. Отслеживайте и оптимизируйте энергопотребление вашего приложения, чтобы решить эту проблему.
Размер APK. Размер вашего APK напрямую влияет на объем памяти устройства ваших пользователей и время загрузки вашего приложения. Стремитесь к тому, чтобы размер APK был как можно меньшим без ущерба для функций и качества.
Использование памяти. Неэффективное использование памяти может привести к замедлению работы и сбоям приложений, особенно на устройствах низкого уровня. Постоянно отслеживайте и оптимизируйте использование памяти вашим приложением, чтобы свести к минимуму проблемы.
Использование сети. Высокое использование сети влияет не только на скорость вашего приложения, но и на тарифные планы пользователей. Оптимизируйте сетевые запросы и ответы, чтобы минимизировать использование сети и повысить производительность приложений.
Время рендеринга кадра. Плавная анимация и переходы жизненно важны для удобства пользователя. Стремитесь к тому, чтобы время рендеринга кадров не превышало 16 мс, чтобы обеспечить плавную работу со скоростью 60 кадров в секунду.







