Отключаем Jetifier и ускоряем сборку: опыт Тинькофф.Бизнес
Привет, Хабр!
Уже пять лет наша команда разрабатывает Тинькофф.Бизнес — мобильный банк для юридических лиц и ИП. За это время наше android-приложение успело набрать целых 200 модулей и 400 тысяч строк компилируемого кода.
Модуляризация приложения не всегда идет ему на пользу. Нам приходится решать большое количество задач и проблем, связанных со скоростью сборки.
В этой статье я расскажу и покажу, как мы ускорили билд, отключив Jetifier.
Преамбула
Jetifier был представлен еще в далеком 2018 году вместе с AndroidX — классной заменой support
библиотекам, компоненты которой могут поддерживаться и обновляться независимо друг от друга.
Сам по себе Jetifier довольно сложен, но принцип его работы прост как три копейки: он проходится по всем библиотекам, которые есть у вас в проекте и заменяет в них android.support
зависимости на их androidx
аналог.
В результате мы получаем еще один шаг сборки, который может занять довольно много времени, а до появления AGP 4.1.0 еще и никак не кэшировал результат своего выполнения и замедлял даже инкрементальный билд.
Конечно же нам хотелось бы избавиться от него. Как?
Отключаем Jetifier
На самом деле все может быть довольно просто. Попробуйте зайти в gradle.properties
и проставить там заветный android.enableJetifier=false
, а затем выполнить Gradle sync и build. Получилось? Если нет — вы увидите примерно следующую ошибку:
Это связано с тем, что в classpath есть легаси android.support
зависимость, и она конфликтует с ее androidx-аналогом. Для отключения Jetifier’а нужно сделать так, чтобы в графе зависимостей не было ни одной саппорт-библиотеки. Давайте посмотрим на полный список зависимостей в нашем проекте. Открываем терминал и запускаем следующую команду:
./gradlew :app:dependencies --configuration=releaseRuntimeClasspath
Здесь можно видеть, что модуль app
использует mosby-mvp
, который тянет за собой support
-библиотеки.
В случае, если ваш проект довольно большой и имеет много зависимостей, :app:dependencies
может быть не совсем удобным способом отлавливать легаси-зависимости, на этот случай можно использовать плагин Can I Drop Jetifier: он анализирует граф зависимостей проекта и смотрит, есть ли среди них те, что ссылаются на android.support
библиотеки, агрегируя их в один список.
Давайте применим плагин и вызовем ./gradlew -Pandroid.enableJetifier=false canIDropJetifier
Теперь вместо большого лога зависимостей мы можем видеть только те, что мешают нам выключить Jetifier.
Отлично! Давайте теперь на примере mosby.mvp
рассмотрим способ миграции библиотеки на androidx
.
Для этого нам нужно выполнить несколько шагов:
Проверить версию библиотеки — если есть более новая, в которой нет
support
зависимостей — обновляемся. Если нет — переходим на следующий шаг.Найти библиотеку в репозиториях. Например,
mosby.mvp
лежит на mavenСкачиваем
.pom
и.aar
файлы.Открываем
.pom
файл и меняем
— добавляем в него префиксjetified.
, чтобы ничего не перепутатьВручную заменяем все
android.support
зависимости на ихandroidx
аналог, воспользовавшись этими маппингами.Если зависимости содержат другие артефакты из этой группы, использующие
android.support
— с ними придется провести такую же процедуру.Скачиваем jetifier-standalone и прогоняем через него скачанный
.aar
файл с зависимостью../jetifier-standalone -i
-o Загружаем
.pom
и.aar
файлы в любой доступный вам менеджер репозиториев. У нас это Nexus, если же у вас его нет — можете просто положить .aar к себе в проект.
Готово! Выполнив эти шаги, мы получаем jetified-артефакт, который можем использовать у себя в проекте.
Давайте посмотрим, какой выигрыш мы от этого получили.
Метрики
Для сбора метрик отлично подойдет Gradle Profiler. Для его запуска мы написали простой .sh
скрипт и положили его в корневую папку проекта.
#!/bin/bash
echo "Cloning gradle-profiler repository..."
git clone https://github.com/gradle/gradle-profiler.git
cd gradle-profiler
./gradlew installDist
cd ..
./gradle-profiler/build/install/gradle-profiler/bin/gradle-profiler --benchmark --iterations 4 --warmups 3 --project-dir ./ :rko:assembleDebug
echo "searching for statistics..."
medians=$(grep "median" profile-out/benchmark.csv)
IFS=', ' read -r -a array <<< "$medians"
echo "configurationTime = ${array[1]}"
echo "syncTime = ${array[2]}"
...
Далее после прогона мы получили следующие метрики:
Метрика | Jetified | Non-Jetified |
Mean | 23,5 sec | 28,5 sec |
Min | 22 sec | 26 sec |
Max | 25 sec | 31 sec |
У нас было не так много легаси-зависимостей, которые пришлось перевести на androidx руками, но тем не менее, прогнав на них Jetifier, нам удалось отнять целых 5 секунд из среднего времени сборки. При большом количестве зависимостей эта цифра будет только расти.
Еще больше метрик и самых разных новостей о Тинькофф.Бизнес можно увидеть у нас в Телеграм-канале Tinkoffhere!