Как уменьшить размер мобильного приложения на iOS и Android
Практика4 минРедакция Innovialabs
Коротко
Сначала измерьте размер загрузки для конкретного устройства в консолях сторов, а затем уменьшайте его по порядку: App Bundle и App Thinning, R8, сжатие картинок и шрифтов, удаление лишних SDK и вынос редких ресурсов в загрузку по запросу.
Коротко: что реально уменьшает размер
Пользователь скачивает не ваш APK или IPA целиком, а версию, собранную стором под его устройство. Поэтому работа идёт в два шага: измерить реальный размер загрузки и убрать то, что попадает в неё без необходимости. Самые заметные результаты обычно дают:
- публикация через Android App Bundle и включённый App Thinning на iOS;
- R8 (минификация и shrink ресурсов) на Android, strip символов на iOS;
- сжатие и замена тяжёлых картинок, шрифтов, видео и анимаций;
- удаление неиспользуемых SDK и библиотек;
- вынос редко нужного контента в загрузку по запросу.
Как измерить размер правильно
Размер файла сборки на вашем компьютере почти всегда вводит в заблуждение: он включает ресурсы для всех экранов и архитектур.
- Android. В Google Play Console есть отчёт о размере приложения: размер загрузки и установки для типичных конфигураций устройств. Локально помогает APK Analyzer в Android Studio и
bundletool, который собирает APK под конкретное устройство из.aab. - iOS. При экспорте архива в Xcode включите отчёт App Thinning Size Report — он показывает размер для каждого варианта устройства. Итоговые цифры также видны в App Store Connect после обработки сборки.
Фиксируйте размер в каждом релизе. Рост обычно незаметен по одной сборке, но хорошо виден на графике за полгода.
Android: App Bundle и R8
App Bundle (.aab) позволяет Google Play выдавать каждому устройству только нужные ресурсы плотности экрана, языки и нативные библиотеки под его архитектуру. Для новых приложений в Play это стандартный формат.
R8 удаляет неиспользуемый код, сокращает имена и вместе с shrinkResources вычищает неиспользуемые ресурсы:
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
После включения R8 обязательно прогоните тесты релизной сборки: код, вызываемый через рефлексию или сериализацию, может быть удалён, и для него понадобятся правила -keep.
iOS: App Thinning и сборка
App Store сам применяет App Thinning: slicing отдаёт устройству только нужные ассеты и архитектуру. Ваша задача — не мешать ему:
- храните изображения в Asset Catalog, а не россыпью файлов в бандле — так работает выдача по разрешению экрана;
- убедитесь, что в релизе включён strip отладочных символов (dSYM загружайте отдельно для крэш-репортов);
- проверьте, не тянут ли зависимости собственные копии одних и тех же библиотек.
On-Demand Resources позволяют скачивать редкие ресурсы (уровни игры, обучающие видео) уже после установки. На Android аналог — Play Asset Delivery и Play Feature Delivery.
Ресурсы: картинки, шрифты, медиа
Ресурсы часто весят больше кода. Что проверить:
| Ресурс | Что сделать |
|---|---|
| PNG-иллюстрации | Перевести в WebP/HEIC или в векторные форматы |
| Иконки | Использовать векторные (Vector Drawable, SF Symbols, SVG) |
| Шрифты | Оставить только нужные начертания, подмножество символов |
| Видео, онбординг | Загружать с сервера, а не класть в сборку |
| Lottie и анимации | Удалить вложенные растровые картинки, упростить |
| Локализации | Не включать языки, которые не поддерживаете |
Лишние SDK и зависимости
Каждый SDK аналитики, рекламы или чата добавляет код, ресурсы и иногда нативные библиотеки. Раз в квартал проводите ревизию: какие SDK реально используются, какие дублируют друг друга, какие подключены целиком ради одной функции. Удаление одного забытого SDK нередко даёт больше, чем недели оптимизации картинок.
Особенности Flutter и React Native
- Flutter. Собирайте
flutter build appbundleиflutter build ipa, используйте флаг--split-debug-infoи--obfuscate, чтобы вынести отладочную информацию. Команда--analyze-sizeпоказывает, что занимает место. Иконочные шрифты можно урезать через tree shaking иконок (по умолчанию включён в релизе). - React Native. Включите Hermes — байткод обычно компактнее и быстрее стартует. Включите R8 в Android-проекте, проверьте бандл JS на тяжёлые зависимости (moment-подобные библиотеки с локалями, полные наборы иконок).
Частые ошибки
- Смотреть на размер локального файла вместо отчётов стора.
- Включить R8 без тестов релиза и получить крэш в продакшене.
- Хранить онбординг-видео и большие картинки в сборке.
- Подключать SDK «на будущее» и никогда его не удалять.