Install completion drops as download size rises, and the effect is sharpest on slow connections and cheaper devices — which is most of the world. Here is what actually reduces an Android app's size, in order of return on effort.
1. Ship an App Bundle (biggest single win)
If you are still publishing a universal APK, this one change usually cuts 15–35% on its own. Play generates a per-device APK containing only the language, density and ABI that device needs, instead of shipping all of them to everyone. Nothing in your code has to change.
2. Turn on R8 shrinking and resource shrinking
In your release build type:
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
}
minifyEnabled removes unused code and shortens names. shrinkResources removes resources nothing references. Test the release build properly afterwards — anything reached only by reflection needs a keep rule, and the failure mode is a runtime crash, not a build error.
3. Fix your images
For most apps that are not games, images are the largest single category.
- Use WebP instead of PNG or JPEG. Typically 25–35% smaller at the same quality. Android Studio converts in place: right-click a drawable → Convert to WebP.
- Use vector drawables for icons and simple shapes. One small XML replaces five PNG densities.
- Stop shipping oversized bitmaps. A 4000px photo displayed in a 200dp view is wasted bytes in the download and wasted memory at runtime.
- Do not hand-generate icon densities at the wrong sizes — the icon generator emits the correct ladder so you are not shipping a 512px launcher icon to an mdpi device.
4. Audit your dependencies
A single convenience library can cost more than every image in your app. Build the APK Analyzer report (Build → Analyze APK) and look at what is actually large.
Common offenders:
- Pulling in all of Google Play Services instead of only the modules you use.
- Heavyweight image loaders when you load three images.
- Full HTTP stacks duplicated because two libraries each bundle their own.
- Test or debug libraries leaking into the release configuration.
5. Remove unused languages
If your app only ships English and Hindi strings but your libraries carry 70 locales, you are downloading translations nobody reads:
android {
defaultConfig {
resourceConfigurations += ["en", "hi"]
}
}
6. Move large assets out of the binary
Big on-boarding videos, level packs, high-resolution imagery and ML models do not need to be in the initial download. Play Feature Delivery lets you install modules on demand, and Play Asset Delivery handles large asset packs. Both mean a smaller first install and faster time to a usable app.
Measure the number that matters
The size of your AAB file is not what users download. Play Console → App bundle explorer shows the actual delivered download size per device configuration. Optimise against that, and check it again after each release — size regressions creep in quietly with new dependencies.
Do the ordering above in order. Teams routinely spend a week hand-compressing images for a 2% gain while shipping a universal APK that costs them 30%.