Как Собирать Аналитику И Не Убивать Продуктивность

Аналитика — неотъемлемая часть современного мобильного приложения.

Аналитика позволяет собирать информацию о пользователе с целью развития и улучшения продукта.

Зачастую сбор информации снижает производительность приложений.

Процесс дополнительно нагружает процессор и память, а это высокая цена.

Медленная работа приложения может вызвать негативные отзывы пользователей, снизить рейтинги и привести к потере аудитории.

Наша команда Android-разработчиков также столкнулась с этой проблемой во время работы над другим проектом, связанным с новостями.

Нам нужно было прописать отображение каждой новости в списке.



Попытка №1

Получив задачу по сбору аналитики, команда быстро показала результат. Триггером генерации события стал метод onViewAttachedToWindow .

Вроде бы всё было хорошо, но при быстрой прокрутке интерфейс заметно подвисал — что-то пошло не так.

Проблему нужно было решить.

Каждый переживает замерзание по-разному, поэтому нам нужны были факты и доказательства.

Для измерения заикания мы выбрали показатель FPS (Frames Per Second), а для измерения показателя — FPS-метр.

Крошечный плотнее .

После подключения утилиты команда получила объективное подтверждение проблемы — показатель падал, порой весьма ощутимо: менее 30 кадров в секунду, запись экрана с включенной утилитой показана на рисунке 1.

Как собирать аналитику и не убивать продуктивность

Рисунок 1. Запись экрана перед оптимизацией

Попытка №2

Что, если мы отложим отправку событий, пока пользователь прокручивает список? «Хммм», — подумала команда и решила создать очередь событий и отправлять ее после остановки прокрутки.

Здесь все просто: добавьте OnScrollListener В RecyclerView и подожди, пока новое состояние будет гладким SCROLL_STATE_IDLE — проблема частично решена.

   

class IdleStateScrollListener(private val analyticsFacade: AnalyticsFacade) : RecyclerView.OnScrollListener() { fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { analyticsFacade.setPending(newState != RecyclerView.SCROLL_STATE_IDLE) } }

Следующим шагом является реализация накопления и отправки событий.

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

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

Это сразу дало результат, значительный прирост FPS. В принципе проблема решилась; на рисунке 2 мы видим результат работы приложения после второй попытки.

Но осталась одна проблема — в сервис отправлялись события, что приводило к частой генерации объектов классов.

Намерение , и это дополнительно загружается Г.

К.

и приносил «удовольствия» в виде остановить мир делает паузу.



Как собирать аналитику и не убивать продуктивность

Рисунок 2. Запись экрана после второй попытки

Попытка №3

«Отправка не одного события за раз, а списка событий — еще одна отличная идея», — подумали в команде.

После небольшой доработки класса команда реализовала отправку событий с помощью списка и получила стабильные значения показателя на уровне 55–60 кадров в секунду (рис.

3).



Как собирать аналитику и не убивать продуктивность

Рисунок 3. Запись экрана после третьей попытки

Выводы

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

Надеюсь, наш опыт будет полезен как новичкам, так и опытным разработчикам.



Можно ли было сделать что-то еще?

Наша команда остановилась на третьем варианте, но это не единственный вариант, который можно применить.

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

Тогда преобразование будет происходить при прокрутке в режиме SCROLL_STATE_IDLE .

Также можно было создать пул объектов для событий.

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

Теги: #Android #оптимизация производительности #recyclerview #песочница #Разработка мобильных приложений #Разработка Android

Вместе с данным постом часто просматривают: