Binary size reduction
Agent skills for profiling and optimizing mobile app performance (startup, memory, frame-rate, network).
npx -y skills add almasumdev/awesome-mobile-performance-agent-skills --skill binary-size-reductionAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Shrink APK/AAB and IPA size with R8/ProGuard, dead-code elimination, asset hygiene, and Android App Bundle / App Thinning best practices.
SKILL.md
5.6 KB, as published. Nobody here has run it
Binary Size Reduction
Instructions
Binary size affects install conversion, update friction, and in emerging markets, whether the app is installed at all. Cut with a combination of code shrinking, asset hygiene, and store delivery features.
1. Budgets
| Platform | Download (p50 device) | On-disk |
|---|---|---|
| Android (AAB download split) | ≤ 25 MB | ≤ 80 MB |
| iOS (thinned download) | ≤ 60 MB | ≤ 150 MB |
2. Android — R8 Full Mode
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
gradle.properties:
android.enableR8.fullMode=true
Full mode enables aggressive optimizations, horizontal class merging, and method inlining. Expect 10–25% additional shrink on a typical modern app.
3. ProGuard Rules — Only What You Need
Keep rules narrow. Every -keep class com.example.** line prevents shrink on that tree.
Good:
-keepclassmembers class * {
@com.squareup.moshi.FromJson *;
@com.squareup.moshi.ToJson *;
}
Bad (overly broad):
-keep class com.example.** { *; }
Audit with build/outputs/mapping/release/usage.txt — it lists everything R8 kept.
4. Android — App Bundles and Delivery
-
Ship AAB, not APK. Play's Dynamic Delivery slices per ABI, density, and language.
-
Use Dynamic Feature Modules for rarely-used features (onboarding, premium flows).
-
Play Asset Delivery for large assets (ML models, tilesets) — do not bundle in the base module.
-
Remove unused languages: in
build.gradle,android { defaultConfig { resConfigs("en", "es", "fr", "de", "ja", "pt", "ru", "zh") } }
5. Android — Native Libraries
- Ship only the ABIs you need:
abiFilters = setOf("arm64-v8a", "armeabi-v7a"). Avoid x86/x86_64 unless you target emulators. - Enable ndk { debugSymbolLevel = "SYMBOL_TABLE" } and upload debug symbols to Play; do not keep symbols in the shipping binary.
- Use 16 KB page sizes (Android 15+) alignment — some NDK libs get smaller when built with
-Wl,-z,max-page-size=16384.
6. iOS — App Thinning and Bitcode Sunset
- Xcode 14 removed Bitcode; do not re-enable it. Waste of time.
- App Thinning: ship from a universal IPA to the App Store; users download a per-device slice.
- Prefer Asset Catalogs with device variants (1x/2x/3x) — the store strips unused slices.
- On-Demand Resources (ODR) for tutorial videos, levels, locale packs.
7. iOS — Dead Code Stripping
Ensure Build Settings:
DEAD_CODE_STRIPPING = YES
STRIP_INSTALLED_PRODUCT = YES
DEPLOYMENT_POSTPROCESSING = YES
GCC_OPTIMIZATION_LEVEL = s // Swift: -Osize
SWIFT_OPTIMIZATION_LEVEL = -Osize
Swift -Osize often saves 5–10% over -O.
8. Asset Hygiene (Both Platforms)
- Replace PNGs with WebP lossless or AVIF; often 30–50% smaller.
- SVG/Vector drawables for icons. Avoid ship of multiple density PNGs for vector art.
- Compress JPEGs:
mozjpegat q=82. - Strip EXIF with
exiftool -all=. - Avoid shipping fonts you do not use. A single font family with 4 weights > 400 KB can bloat quickly.
Gradle task to detect unused resources:
./gradlew lintDebug | Select-String "UnusedResources"
9. Analyze What's Inside
Android:
./gradlew bundleRelease
# open with Android Studio -> Build -> Analyze APK
The APK Analyzer breaks down .dex size per package. Look for:
- Oversized kotlin/swift standard libraries bundled by mistake.
- Duplicate libs from transitive dependencies (e.g.,
okiotwice). - Large JSON/text assets — move to
Play Asset Delivery.
iOS: open the .ipa in the Organizer or unzip and inspect:
unzip -l App.ipa
du -sh Payload/App.app/Frameworks/*
Large .framework entries often come from analytics SDKs; evaluate whether you can swap for smaller alternatives.
Flutter: flutter build appbundle --analyze-size produces a size report JSON plus a DevTools view.
React Native: npx react-native-bundle-visualizer and Hermes .hbc inspection.
10. Dependency Hygiene
- Every dependency costs bytes. Review each one; remove any that solves a 10-line problem.
- Prefer single-purpose libs over kitchen-sink frameworks.
- Use R8/ProGuard tree-shaking by avoiding reflection-heavy libraries in hot paths (Gson → Moshi/kotlinx.serialization).
11. Track Regressions
Fail CI if APK size grows > 2% without an opt-in flag. Store the mapping file and the size-report.json per release.
GitHub Action example:
- name: Fail on APK regression
run: scripts/compare-apk-size.sh artifacts/app-release.aab
Checklist
- R8 full mode enabled; shrinkResources on.
- ProGuard rules audited; no broad
-keep **entries. - AAB shipped; ABIs limited to arm64 + armv7; unused languages stripped.
- Dynamic Feature / On-Demand Resources for rare / heavy assets.
- iOS Swift optimization =
-Osize; dead code stripping on. - Assets: WebP/AVIF, stripped EXIF, minimal font weights.
- Bundle analyzer run per release; regressions explained.
- CI gate fails build on > 2% size regression.