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

С первого квартала этого года команда Search Apps Redfin потратила много времени на оценку и улучшение производительности наших мобильных приложений для iOS и Android. Мы улучшили время «холодного старта» на 28%, следуя нескольким основным методам.

Определение холодного старта

Холодный запуск происходит, когда пользователь запускает приложение и не имеет предыдущего сеанса, работающего в фоновом режиме. Мы решили сосредоточиться на времени холодного старта, потому что считаем, что оно существенно влияет на пользовательский опыт (измеряемый по удержанию пользователей).

Мы рассмотрели два разных типа холодного старта для нашего приложения для Android: запуск на «Экране карты» и «Экран с домашними данными».

Когда пользователи запускают наше приложение с главного экрана своего устройства, мы сначала показываем наш «Экран карты» - карту близлежащих домов, выставленных на продажу. Затем пользователи могут нажать на конкретный дом, чтобы перейти на наш «Экран сведений о доме», где мы отображаем все сведения об этом конкретном доме.

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

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

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

Покажи мне деньги!

Последние пару кварталов мы отслеживали время холодного старта в statsD. Вот посмотрите, где мы сейчас находимся, отслеживая наши медианные и верхние 90 за последнюю неделю:

Это огромное улучшение по сравнению с тем, чем мы были в первом квартале. Чтобы подчеркнуть это, вот краткое сравнение:

                Q1      Q3      % Improvement
                ----    ----    -------------
Upper 90        5.3s    3.8s    28.30%
Median          2.4s    1.75s   27.08%

Пока наше приложение запускается на экране карты, оно на самом деле является оболочкой для SDK Google Maps. Это делает приложение Google Maps отличным эталоном, и мы должны стремиться к нему. На Nexus 5x время холодного запуска уменьшилось с ~ 157% до ~ 112%.

Какие улучшения мы внесли?

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

Улучшения десериализации состояния приложения - улучшение на 500 мс

При запуске нашего приложения мы сначала десериализуем наш AppState. Он содержит все сохраняемые данные, необходимые для перезапуска приложения с единообразным взаимодействием для наших пользователей. Он содержит все: от переключателей функций (мы называем их вышибалы) до статуса входа в систему и данных отслеживания; все наше приложение зависит от его доступности. Как вы понимаете, это может быть масса данных. Мы внесли два улучшения, чтобы ускорить десериализацию всех этих данных:

  1. Переход с двоичного кода Java на сериализацию JSON. Это намного быстрее и сложнее нарушить обратную совместимость.
  2. Параллельная десериализация этих данных. Мы уже разделили эти данные на разные файлы, чтобы ошибка в одном файле не нарушала работу всего AppState. Теперь мы читаем все эти данные параллельно, а не последовательно.

Переход на Dagger для внедрения зависимостей - улучшение на 300 мс

В течение многих лет мы использовали Roboguice для внедрения зависимостей в нашем Android-приложении. Это версия знакомой библиотеки Guice, оптимизированная для Android. Однако Roboguice полагается на множество рефлексий для внедрения, что приводит к очень медленной работе в мобильных приложениях. Roboguice также прекратил активную разработку в прошлом году и больше не является поддерживаемой библиотекой.

С тех пор мы перешли на Dagger, которая в настоящее время является самой популярной библиотекой Android DI. Он фокусируется на гораздо большей генерации кода времени компиляции, пропуская необходимость отражения, и, следовательно, намного более производительный.

Кэширование данных отслеживания аналитики - улучшение на 300 мс

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

Задержка наполнения нижнего края содержимого - улучшение на 500 мс главного экрана сведений

Наш экран с подробными сведениями о доме - это действительно длинный ScrollView, который демонстрирует массу информации о доме. Раньше мы раздували сразу все просмотры на этом экране, что оказывалось очень медленным. Чтобы улучшить это, мы вместо этого решили разделить контент на раздел «вверху сгиба» и раздел «ниже сгиба». Наш контент в верхней части экрана содержит виды, показанные в верхней части экрана, с которыми мы хотим, чтобы пользователь мог взаимодействовать как можно скорее, включая фотогалерею, цену, кровати, ванны и т. Д. -складываемый контент содержит все другие виды, включая описание объявления, карту района, историю собственности и многое другое.

Разделив наши взгляды на эти две категории, мы смогли раздуть их по отдельности. Мы по-прежнему синхронно увеличиваем объем содержимого над сгибом, когда создается Фрагмент, содержащий нашу страницу. Однако мы смогли использовать AsyncLayoutInflater, чтобы раздувать наш нижний контент в фоновом потоке, а затем публиковать его обратно в основной поток для визуализации, когда он был готов для просмотра пользователем. Таким образом, контент в нижней части страницы больше не замедлялся, показывая пользователю самый важный контент.

Что дальше?

Основываясь на нашем текущем тестировании холодного запуска, мы чувствуем себя довольно комфортно с текущим состоянием нашего холодного запуска для отображения времени экрана. Мы продолжим мониторинг этой области, чтобы избежать регресса, но дальнейшая работа не запланирована. В будущем мы можем определить другие области для улучшения производительности (например, время поиска, использование памяти и т. Д.).