Увеличьте скорость сборки в 3 раза, следуя этим простым рекомендациям

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

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

Чтобы помочь контекстуализировать и показать влияние этих советов, я собираюсь использовать проект Google Santa Tracker Android в качестве руководящего примера.

Помните: время сборки сильно зависит от характеристик вашего проекта и среды сборки.

Прежде чем перейти к этим советам, нам нужно быстро просмотреть 3 стандартных сценария сборки.

  • Полная сборка (чистая сборка отладки)
  • Инкрементальная сборка: изменение Java (однострочное изменение Java в реализации метода)
  • Инкрементальная сборка: изменение ресурса (простое добавление или удаление строкового ресурса)

Совет 1. Используйте последнюю версию подключаемого модуля Android Gradle

Первый совет может показаться самоочевидным, но о нем стоит упомянуть. Убедитесь, что вы используете последнюю версию Android Gradle plugin.

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

Полученные результаты

После перехода со старого плагина Gradle 2.2.0 на 3.0-alpha1 мы сократили 25% полной сборки, 38 % от постепенного изменения Java и около 16% от изменения ресурса.

Совет 2. Избегайте устаревших multidex

Как вы, вероятно, знаете, если ваше приложение превышает лимит ссылок на методы в 64 КБ, вам нужно будет использовать multidex.

Но вы можете не знать, что если ваша minSDKVersion ниже 21 (до Lollipop) и вы используете multidex, вы будете использовать устаревшую версию, что значительно замедлит время сборки.

Android Studio 2.3+ автоматически этого избегает.

Полученные результаты

Используя последнюю версию multidex, мы сократили еще 5 секунд из полной сборки и 8 секунд из инкрементального изменения Java. Инкрементальная сборка для изменения ресурса примерно такая же, как и следовало ожидать.

Совет 3. Отключите мульти-APK

Совет № 3 - отключить мульти-APK из вашей разработки. Обычно это делается с помощью Разделить блок в DSL (доменно-ориентированный язык).

Multi-APK позволяет определять размеры, когда вы хотите создать несколько SDK. Таким образом, нет необходимости в сборке для разработки.

Но вы не можете просто отключить создание нескольких APK в разделенном блоке, потому что этот блок является глобальным для всех ваших вариантов сборки (например, для производства и разработки). Один из способов сделать это правильно - определить свойство, подобное devBuild (как показано ниже), и если Gradle увидит это свойство, он установит для splits.abi и splits.density значение false, и генерация нескольких APK не произойдет.

Полученные результаты

Как вы можете видеть на скриншоте ниже, есть еще несколько улучшений по всем направлениям.

Совет 4. Включите минимум ресурсов

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

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

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

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

Кроме того, вы можете упаковать только с английским переводом:

Полученные результаты

Как видно ниже, мы сократили еще 6 секунд после полной сборки, уменьшили 24% на добавочное изменение Java и 21% на добавочное изменение ресурсов.

Совет 5. Отключите сжатие PNG

Затем мы можем отключить сжатие PNG. По умолчанию APPT будет обрабатывать ваши PNG, чтобы уменьшить их размер, чтобы уменьшить размер APK.

Опять же, это замечательно для вашего релизного APK, но не подходит для сборок для разработки.

Поэтому, чтобы избежать проблем с PNG, мы можем использовать то же свойство, которое мы обсуждали в совете 3. Если Gradle видит это свойство, он установит для aaptOptions.cruncherEnabled значение false.

Полученные результаты

Это числа после отключения обработки PNG. Как видите, мы сократили полную сборку на 9 секунд. Однако два других сценария сборки не сильно изменились.

Совет 6. Используйте мгновенный запуск

Мгновенный запуск представлен в Android Studio 2.0.

Компромисс в том, что Instant Run работает только с API 21 или выше. Это не означает, что минимальный SDK вашего приложения не может быть установлен на более низкое значение. Это просто означает, что устройство, на котором вы запускаете Instant Run, должно иметь API 21 или выше.

В Android Studio теперь есть несколько кнопок, которые управляют перезапуском приложения:

  • Выполнить развернет все изменения и перезапустит приложение.
  • Применить изменения изменит ваш ресурс и изменения кода и перезапустит только действие без перезапуска приложения.

Полученные результаты

Это число, которое мы получили после использования Instant Run. На самом деле мы регрессировали на 7 секунд для полной сборки. Но обратите внимание, что для дополнительных изменений мы уменьшили каждое на 3 секунды.

Совет 7. Избегайте непреднамеренных изменений

Совет 7 - забавный. По сути, вам следует избегать непреднамеренных изменений в вашем проекте.

Взгляните на приведенный ниже фрагмент кода. На первый взгляд, код очень разумный - в основном используется текущий DateTime в качестве кода версии для вашего приложения. Это разумный поступок, потому что каждый раз, когда вы строите, вы хотите иметь УНИКАЛЬНЫЙ ID, чтобы, когда ваша команда QA регистрирует ошибку, они могут сказать вам, какая это была сборка.

Но на самом деле это плохо: он заставляет манифест Android изменяться с каждой сборкой, даже если вы не отдаете сборку производственной среде или группе тестирования (QA).

Результаты

Это влияние на файл манифеста при использовании этого DateTime кода версии: добавлено 3 секунды к инкрементальной сборке Java и 3,6 секунды к сборке с инкрементным изменением ресурсов. Это здорово. И это время, потраченное без уважительной причины.

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

Если вариант сборки совпадает с разработкой, тогда нет необходимости устанавливать DateTime,, как показано в приведенном ниже фрагменте кода:

if (variant.productFlavors[0].name == "development") {
    outputFileName = "Build-Development" + "_" + versionName + "_" + versionCode + ".apk"

Совет 8. Не используйте динамические версии Gradle

Следует избегать использования динамических версий различных зависимостей. Gradle предоставляет очень удобный способ использовать последнюю версию данной библиотеки с помощью этого символа плюса (+).

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

Чтобы избежать этой проблемы, всегда используйте определенные версии зависимостей - не используйте символ плюса (+). Как на скриншоте ниже кода.

Совет 9. Следите за памятью

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

В Android Studio, когда вы создаете новый проект, по умолчанию Android предоставляет Gradle 1,5 гигабайта памяти. Это может быть хорошей настройкой для вашего проекта или плохой - это действительно зависит от характеристик вашего проекта.

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

Еще одна вещь, которую я хочу здесь упомянуть, это то, что в DSL (Domain Specific Language) у нас также есть dexOptions, который позволяет вам установить javaMaxHeapSize для процесса dex.

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

Совет 10. Включите кеширование Gradle

Последний (но не менее важный) совет - включить кеширование Gradle. Это новый механизм кеширования для Gradle, в котором вы можете кэшировать все выходные данные каждой задачи.

Это отличается от кеша сборки Android, представленного в Gradle 2.3, который кэшировал только внешние библиотеки pre-dex.

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

Чтобы включить это, просто установите org.gradle.caching=true в свой gradle.properties file.

Полученные результаты

Это результаты, которые я получил после включения кеша. Мы сократили время полной сборки на 7 секунд. Инкрементное изменение Java осталось прежним, а инкрементное изменение ресурса увеличилось на 0,5 секунды.

Суммарные результаты:

Вот совокупный результат после применения всех этих советов. Наша полная сборка выполняется в 3 раза быстрее; инкрементное изменение Java выполняется в 12 раз быстрее, а инкрементное изменение ресурсов - в 3 раза.

Заключение

В этой статье мы узнали, как ускорить сборку Android, следуя нескольким действительно простым советам.

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

Я написал другой контент, связанный с Android, и если вам понравилось то, что вы здесь прочитали, вам, вероятно, также понравится:







Делиться (знаниями) - это забота 😊 Спасибо, что прочитали эту статью. Не забудьте аплодировать или порекомендовать эту статью, если вы нашли ее полезной. Это очень много значит для меня.

Если вам нужна помощь, присоединяйтесь ко мне в Twitter, LinkedIn, GitHub и Facebook .

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

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

Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее создавать лучшие модели машинного обучения.