Skip to content
Innovialabs

How to Reduce Mobile App Download Size on iOS and Android

Practice4 min

In short

Measure the per-device download size in the store consoles first, then shrink it in order: app bundles and app thinning, R8, compressed images and fonts, removing unused SDKs and moving rare content to on-demand delivery.

The short answer

Users never download your whole APK or IPA. The store builds a variant for their specific device. So the work has two steps: measure the real download size, then remove whatever ends up in it without a reason. The biggest wins usually come from:

  • publishing an Android App Bundle and relying on App Thinning on iOS;
  • R8 code and resource shrinking on Android, symbol stripping on iOS;
  • compressing or replacing heavy images, fonts, video and animations;
  • removing unused SDKs and libraries;
  • moving rarely needed content to on-demand delivery.

How to measure size correctly

The size of the build file on your machine is misleading: it contains resources for every screen density and CPU architecture.

  • Android. Google Play Console has an app size report with download and install sizes for common device configurations. Locally, use the APK Analyzer in Android Studio and bundletool, which generates device-specific APKs from an .aab.
  • iOS. When exporting an archive in Xcode, enable the App Thinning Size Report. It lists the size for each device variant. App Store Connect also shows sizes after the build is processed.

Record the size for every release. Growth is invisible from one build to the next but obvious on a six-month chart.

Android: App Bundle and R8

An App Bundle (.aab) lets Google Play serve each device only the screen density resources, languages and native libraries it needs. It is the standard publishing format for new apps on Play.

R8 removes unused code, shortens names and, together with shrinkResources, strips unused resources:

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

After enabling R8, test the release build properly. Code reached through reflection or serialization can be removed, and you will need -keep rules for it.

iOS: App Thinning and build settings

The App Store applies App Thinning automatically: slicing delivers only the assets and architecture a device needs. Your job is to not get in its way:

  • keep images in an Asset Catalog instead of loose files in the bundle, so resolution-specific delivery works;
  • make sure debug symbols are stripped in release builds (upload dSYMs separately for crash reporting);
  • check whether dependencies ship their own copies of the same libraries.

On-Demand Resources let you download rare content (game levels, tutorial videos) after installation. The Android equivalents are Play Asset Delivery and Play Feature Delivery.

Assets: images, fonts, media

Assets often weigh more than code. What to check:

AssetWhat to do
PNG illustrationsConvert to WebP/HEIC or vector formats
IconsUse vectors (Vector Drawable, SF Symbols, SVG)
FontsKeep only the weights you use, subset glyphs
Video, onboardingStream from a server instead of bundling
Lottie and animationsRemove embedded bitmaps, simplify
LocalizationsDrop languages you do not support

Unused SDKs and dependencies

Every analytics, ads or chat SDK adds code, resources and sometimes native libraries. Audit them every quarter: which SDKs are actually used, which overlap, which are included in full for a single feature. Removing one forgotten SDK often saves more than weeks of image tuning.

Flutter and React Native specifics

  • Flutter. Build with flutter build appbundle and flutter build ipa, and use --split-debug-info with --obfuscate to move debug info out of the binary. The --analyze-size flag shows what takes space. Icon fonts are tree-shaken in release builds by default.
  • React Native. Enable Hermes: its bytecode is usually more compact and starts faster. Turn on R8 in the Android project and check the JS bundle for heavy dependencies such as date libraries with all locales or full icon sets.

Common mistakes

  • Looking at the local file size instead of store reports.
  • Enabling R8 without testing the release build and crashing in production.
  • Bundling onboarding videos and large images.
  • Adding SDKs "for later" and never removing them.

FAQ

The store builds a device-specific variant and compresses it for download. The installed size differs again: files are unpacked, and on Android code may be compiled after installation.

We can help with this

If you'd rather get the result than figure it all out yourself — this is what we do every day.

Discuss a project

Read next

Have an idea or a task? Tell us about it

We'll reply within one business day and propose a solution. The consultation is free.