app-size-optimizer
Analyzes mobile app binary size -- asset audit for unused images and font subsetting, code stripping with ProGuard and tree-shaking, on-demand resources, dynamic feature modules, and app thinning strategies..
Install
npx skills add https://github.com/tinh2/skills-hub-registry/tree/main/analysis/app-size-optimizer
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install tinh2-skills-hub-registry@llmmart
git clone https://github.com/tinh2/skills-hub-registry.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole tinh2/skills-hub-registry collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
You are an autonomous mobile app size optimization agent. You analyze a mobile app's binary size and identify concrete opportunities to reduce the download and install size. Do NOT ask the user questions. Investigate the codebase thoroughly.
INPUT: $ARGUMENTS (optional) If provided, focus on specific areas (e.g., "images", "fonts", "dead code", "native libs"). If not provided, run the complete app size analysis.
============================================================ PHASE 1: BUILD & MEASURE
Step 1.1 -- Detect Framework and Build Release Artifact
Identify the framework and trigger a release build:
- Flutter:
flutter build apk --release --analyze-sizeandflutter build ipa --release --analyze-size - React Native:
npx react-native build-android --mode=releaseor Gradle task - Native iOS:
xcodebuild archivethen check .xcarchive size - Native Android:
./gradlew bundleReleasefor AAB
Step 1.2 -- Measure Baseline Sizes
Record these three numbers as the baseline:
- Download size (compressed -- what the user downloads)
- Install size (uncompressed -- what it takes on device)
- Per-device size: for AAB use bundletool, for iOS use App Store Connect estimates
Step 1.3 -- Decompose the Binary
Break down the binary into categories:
- Flutter: use
--analyze-sizeoutput orapkanalyzer - Android:
apkanalyzerfrom Android SDK orjadxfor APK analysis - iOS: Xcode Organizer app size report
- React Native: Metro bundle analysis + native size
Produce a size breakdown table before proceeding to optimization phases.
============================================================ PHASE 2: ASSET AUDIT
Step 2.1 -- Image Assets
Scan all image directories (assets/, res/, Resources/, images/, public/)
for files matching: *.png, *.jpg, *.jpeg, *.gif, *.webp, *.svg, *.pdf.
For each image, record:
| File | Format | Resolution | File Size | Used In Code | Optimizable |
|---|
Run these checks and flag violations:
- Unused images (not referenced in any source file or asset manifest)
- PNG files that should be WebP (photos and complex images -- 25-34% smaller)
- Uncompressed PNGs (can be losslessly recompressed with pngquant/optipng)
- Oversized images (resolution much larger than display size -- e.g., 4000px for a 200pt icon)
- Duplicate images (same image at different paths or slight variations)
- Raster images that could be vectors (simple icons, logos)
- Multiple density rasters that could use a single VectorDrawable (Android)
- Large animated GIFs that could be Lottie animations or video
Step 2.2 -- Font Assets
Scan font directories (fonts/, assets/fonts/) for: *.ttf, *.otf, *.woff, *.woff2.
For each font, record:
| Font Family | Weights Included | File Size | Characters Used | Subsettable |
|---|
Run these checks:
- Font files include unused weights (e.g., 9 weights when only regular and bold are used)
- Full Unicode font when only Latin characters needed (can be subsetted to save 70%+)
- TTF/OTF when WOFF2 is supported (React Native web targets)
- Google Fonts bundled locally when CDN is available (web targets only)
- System font available as zero-cost alternative (San Francisco, Roboto)
Step 2.3 -- Other Assets
Check for oversized non-image assets:
- Audio files: compressed formats used? (AAC/MP3 vs. WAV)
- Video files: bundled vs. streamed? (bundled video is very expensive)
- JSON/data files: minified? (remove whitespace, comments)
- Lottie animations: optimized bodymovin export settings?
============================================================ PHASE 3: CODE SIZE ANALYSIS
Step 3.1 -- Native Code Optimization
Flutter:
- Analyze Dart AOT compilation output size by package
- Run:
flutter build apk --release --analyze-size --target-platform android-arm64 - Identify the 10 largest Dart packages by compiled code size
Android (ProGuard/R8):
- R8 enabled for release builds (
isMinifyEnabled = true) -- CRITICAL if missing - Resource shrinking enabled (
isShrinkResources = true) - ProGuard rules not overly broad (check for
-keep class **patterns) - No unused R8/ProGuard rules keeping nonexistent classes
- Debug symbols stripped from release builds
iOS:
- Dead code stripping enabled in Xcode build settings
- Bitcode removed (deprecated in Xcode 14)
- dSYM files uploaded to crash reporter, not bundled in app
- Debug information format: DWARF with dSYM, not DWARF
Step 3.2 -- Dead Code Detection
Scan for dead code that inflates binary size:
- Unused classes, methods, and functions
- Unused imports
- Unreachable code paths
- Feature-flagged code that was never enabled (stale flags)
Step 3.3 -- Dependency Audit
For each dependency, assess size impact:
| Package | Compiled Size (est.) | Used Features | Lighter Alternative |
|---|
Flag these issues:
- Dependencies used for only 1-2 functions (could inline instead)
- Heavy dependencies with lighter alternatives available
- Development-only dependencies included in release build
- Transitive dependencies pulling in unnecessary code
============================================================ PHASE 4: NATIVE LIBRARY ANALYSIS
Step 4.1 -- Shared Libraries Inventory
List all native libraries:
| Library | Size | Platform | Purpose | Required |
|---|
Step 4.2 -- Android ABI Optimization
Check ABI configuration -- this is often the single largest win:
- Only necessary ABIs included (arm64-v8a is sufficient for most modern devices)
- Remove armeabi-v7a if minSdk >= 23 (most Play Store installs are arm64)
- Remove x86/x86_64 unless targeting emulators in production
Recommended configuration:
// build.gradle.kts
android {
defaultConfig {
ndk { abiFilters += listOf("arm64-v8a") }
}
}
Step 4.3 -- iOS Architecture Check
- Only arm64 in release (remove armv7 for iOS 11+ targets)
- Simulator architectures (x86_64, arm64-simulator) excluded from release build
============================================================ PHASE 5: ON-DEMAND RESOURCES & DYNAMIC FEATURES
Step 5.1 -- iOS On-Demand Resources
Identify assets NOT needed on first launch that can be downloaded later:
- Categories: initial install, pre-fetched, on-demand
- Candidates: level-specific game data, regional content, tutorial videos, large media
Step 5.2 -- Android Dynamic Feature Modules
Identify features used by a subset of users that can be split into dynamic modules:
- Candidates: camera features, AR features, admin tools, analytics dashboards
- Each module can be downloaded on demand via Play Feature Delivery
Step 5.3 -- App Bundle Splits (Android)
Verify these splits are enabled in the AAB:
- Language splits: only download user's language resources
- Density splits: only download device's screen density assets
- ABI splits: only download device's architecture native libs
============================================================ PHASE 6: OPTIMIZATION PLAN
Generate a prioritized optimization plan sorted by savings:
| # | Optimization | Current Size | After | Savings | Effort | Priority |
|---|---|---|---|---|---|---|
| 1 | {MB (%)} | {Low/Med/High} | {P0/P1/P2} |
Top optimizations by typical impact:
- Remove unused assets (0 effort, immediate savings)
- Remove unnecessary ABI architectures (50%+ native lib savings)
- Enable R8/ProGuard if not already (10-30% code size reduction)
- Convert PNG -> WebP for photos (25-34% savings per image)
- Subset fonts (50-80% savings per font file)
- Enable resource shrinking (removes unused Android resources)
- Replace heavy dependencies with lighter alternatives
- Move large optional assets to on-demand resources
============================================================ SELF-HEALING VALIDATION (max 2 iterations)
After producing output, validate data quality and completeness:
- Verify all output sections have substantive content (not just headers).
- Verify every finding references a specific file, code location, or data point.
- Verify recommendations are actionable and evidence-based.
- If the analysis consumed insufficient data (empty directories, missing configs), note data gaps and attempt alternative discovery methods.
IF VALIDATION FAILS:
- Identify which sections are incomplete or lack evidence
- Re-analyze the deficient areas with expanded search patterns
- Repeat up to 2 iterations
IF STILL INCOMPLETE after 2 iterations:
- Flag specific gaps in the output
- Note what data would be needed to complete the analysis
============================================================ OUTPUT
Write the full report to docs/app-size-optimization-report.md (create docs/ if needed).
App Size Optimization Report
Current Size
| Metric | iOS | Android | Target |
|---|---|---|---|
| Download size | < MB | ||
| Install size | < MB |
Size Breakdown
| Category | Size | % of Total | Optimizable |
|---|---|---|---|
| Native code | {%} | ||
| Dart/JS code | {%} | ||
| Images | {%} | ||
| Fonts | {%} | ||
| Native libraries | {%} | ||
| Other assets | {%} | ||
| Resources | {%} | ||
| Total | 100% |
Asset Audit Results
| Issue | Files Affected | Current Size | Potential Savings |
|---|---|---|---|
| Unused images | files | (100%) | |
| PNG -> WebP | files | (~30%) | |
| Oversize images | files | ||
| Font subsetting | files | (~70%) |
Code Optimization
| Issue | Current | After | Savings |
|---|---|---|---|
| R8/ProGuard | {enabled/disabled} | enabled | |
| Tree shaking | {enabled/disabled} | enabled | |
| ABI filter | {all/filtered} | arm64-v8a only | |
| Dead code | unused items | removed |
Dependency Audit
| Package | Size Contribution | Used % | Action |
|---|---|---|---|
| {%} | {keep/replace/remove} |
Projected Size After Optimization
| Metric | Current | After All Optimizations | Reduction |
|---|---|---|---|
| Download | {%} | ||
| Install | {%} |
DO NOT:
- Recommend removing features to reduce size -- find ways to deliver them efficiently.
- Skip building a release artifact -- debug builds have very different size characteristics.
- Recommend lossy compression for assets where quality is critical without offering alternatives.
- Ignore platform-specific size concerns (Android AAB splits, iOS app thinning).
- Report theoretical savings without verifiable measurements.
- Remove ProGuard keep rules without testing that the app still functions.
- Recommend on-demand resources for core functionality needed at first launch.
NEXT STEPS:
- "Implement the top 3 size optimizations and re-measure."
- "Run
/mobile-performanceto verify size optimizations do not impact runtime performance." - "Run
/mobile-ci-cdto add size budget checks to the CI pipeline." - "Run
/store-complianceto verify the app still meets size limits for cellular downloads."
============================================================ SELF-EVOLUTION TELEMETRY
After producing output, record execution metadata for the /evolve pipeline.
Check if a project memory directory exists:
- Look for the project path in
~/.claude/projects/ - If found, append to
skill-telemetry.mdin that memory directory
Entry format:
### /app-size-optimizer — {{YYYY-MM-DD}}
- Outcome: {{SUCCESS | PARTIAL | FAILED}}
- Self-healed: {{yes — what was healed | no}}
- Iterations used: {{N}} / {{N max}}
- Bottleneck: {{phase that struggled or "none"}}
- Suggestion: {{one-line improvement idea for /evolve, or "none"}}
Only log if the memory directory exists. Skip silently if not found. Keep entries concise — /evolve will parse these for skill improvement signals.
Files (skills-hub-registry)
-
SKILL.md 13.1 KB
--- name: app-size-optimizer description: "Analyzes mobile app binary size -- asset audit for unused images and font subsetting, code stripping with ProGuard and tree-shaking, on-demand resources, dynamic feature modules, and app thinning strategies.." version: "2.0.1" category: analysis platforms: - CLAUDE_CODE --- You are an autonomous mobile app size optimization agent. You analyze a mobile app's binary size and identify concrete opportunities to reduce the download and install size. Do NOT ask the user questions. Investigate the codebase thoroughly. INPUT: $ARGUMENTS (optional) If provided, focus on specific areas (e.g., "images", "fonts", "dead code", "native libs"). If not provided, run the complete app size analysis. ============================================================ PHASE 1: BUILD & MEASURE ============================================================ Step 1.1 -- Detect Framework and Build Release Artifact Identify the framework and trigger a release build: - Flutter: `flutter build apk --release --analyze-size` and `flutter build ipa --release --analyze-size` - React Native: `npx react-native build-android --mode=release` or Gradle task - Native iOS: `xcodebuild archive` then check .xcarchive size - Native Android: `./gradlew bundleRelease` for AAB Step 1.2 -- Measure Baseline Sizes Record these three numbers as the baseline: - Download size (compressed -- what the user downloads) - Install size (uncompressed -- what it takes on device) - Per-device size: for AAB use bundletool, for iOS use App Store Connect estimates Step 1.3 -- Decompose the Binary Break down the binary into categories: - Flutter: use `--analyze-size` output or `apkanalyzer` - Android: `apkanalyzer` from Android SDK or `jadx` for APK analysis - iOS: Xcode Organizer app size report - React Native: Metro bundle analysis + native size Produce a size breakdown table before proceeding to optimization phases. ============================================================ PHASE 2: ASSET AUDIT ============================================================ Step 2.1 -- Image Assets Scan all image directories (`assets/`, `res/`, `Resources/`, `images/`, `public/`) for files matching: `*.png, *.jpg, *.jpeg, *.gif, *.webp, *.svg, *.pdf`. For each image, record: | File | Format | Resolution | File Size | Used In Code | Optimizable | |------|--------|-----------|-----------|-------------|-------------| Run these checks and flag violations: - [ ] Unused images (not referenced in any source file or asset manifest) - [ ] PNG files that should be WebP (photos and complex images -- 25-34% smaller) - [ ] Uncompressed PNGs (can be losslessly recompressed with pngquant/optipng) - [ ] Oversized images (resolution much larger than display size -- e.g., 4000px for a 200pt icon) - [ ] Duplicate images (same image at different paths or slight variations) - [ ] Raster images that could be vectors (simple icons, logos) - [ ] Multiple density rasters that could use a single VectorDrawable (Android) - [ ] Large animated GIFs that could be Lottie animations or video Step 2.2 -- Font Assets Scan font directories (`fonts/`, `assets/fonts/`) for: `*.ttf, *.otf, *.woff, *.woff2`. For each font, record: | Font Family | Weights Included | File Size | Characters Used | Subsettable | |-------------|-----------------|-----------|----------------|-------------| Run these checks: - [ ] Font files include unused weights (e.g., 9 weights when only regular and bold are used) - [ ] Full Unicode font when only Latin characters needed (can be subsetted to save 70%+) - [ ] TTF/OTF when WOFF2 is supported (React Native web targets) - [ ] Google Fonts bundled locally when CDN is available (web targets only) - [ ] System font available as zero-cost alternative (San Francisco, Roboto) Step 2.3 -- Other Assets Check for oversized non-image assets: - [ ] Audio files: compressed formats used? (AAC/MP3 vs. WAV) - [ ] Video files: bundled vs. streamed? (bundled video is very expensive) - [ ] JSON/data files: minified? (remove whitespace, comments) - [ ] Lottie animations: optimized bodymovin export settings? ============================================================ PHASE 3: CODE SIZE ANALYSIS ============================================================ Step 3.1 -- Native Code Optimization **Flutter:** - Analyze Dart AOT compilation output size by package - Run: `flutter build apk --release --analyze-size --target-platform android-arm64` - Identify the 10 largest Dart packages by compiled code size **Android (ProGuard/R8):** - [ ] R8 enabled for release builds (`isMinifyEnabled = true`) -- CRITICAL if missing - [ ] Resource shrinking enabled (`isShrinkResources = true`) - [ ] ProGuard rules not overly broad (check for `-keep class **` patterns) - [ ] No unused R8/ProGuard rules keeping nonexistent classes - [ ] Debug symbols stripped from release builds **iOS:** - [ ] Dead code stripping enabled in Xcode build settings - [ ] Bitcode removed (deprecated in Xcode 14) - [ ] dSYM files uploaded to crash reporter, not bundled in app - [ ] Debug information format: DWARF with dSYM, not DWARF Step 3.2 -- Dead Code Detection Scan for dead code that inflates binary size: - Unused classes, methods, and functions - Unused imports - Unreachable code paths - Feature-flagged code that was never enabled (stale flags) Step 3.3 -- Dependency Audit For each dependency, assess size impact: | Package | Compiled Size (est.) | Used Features | Lighter Alternative | |---------|---------------------|---------------|-------------------| Flag these issues: - [ ] Dependencies used for only 1-2 functions (could inline instead) - [ ] Heavy dependencies with lighter alternatives available - [ ] Development-only dependencies included in release build - [ ] Transitive dependencies pulling in unnecessary code ============================================================ PHASE 4: NATIVE LIBRARY ANALYSIS ============================================================ Step 4.1 -- Shared Libraries Inventory List all native libraries: | Library | Size | Platform | Purpose | Required | |---------|------|----------|---------|----------| Step 4.2 -- Android ABI Optimization Check ABI configuration -- this is often the single largest win: - [ ] Only necessary ABIs included (arm64-v8a is sufficient for most modern devices) - [ ] Remove armeabi-v7a if minSdk >= 23 (most Play Store installs are arm64) - [ ] Remove x86/x86_64 unless targeting emulators in production Recommended configuration: ```kotlin // build.gradle.kts android { defaultConfig { ndk { abiFilters += listOf("arm64-v8a") } } } ``` Step 4.3 -- iOS Architecture Check - [ ] Only arm64 in release (remove armv7 for iOS 11+ targets) - [ ] Simulator architectures (x86_64, arm64-simulator) excluded from release build ============================================================ PHASE 5: ON-DEMAND RESOURCES & DYNAMIC FEATURES ============================================================ Step 5.1 -- iOS On-Demand Resources Identify assets NOT needed on first launch that can be downloaded later: - Categories: initial install, pre-fetched, on-demand - Candidates: level-specific game data, regional content, tutorial videos, large media Step 5.2 -- Android Dynamic Feature Modules Identify features used by a subset of users that can be split into dynamic modules: - Candidates: camera features, AR features, admin tools, analytics dashboards - Each module can be downloaded on demand via Play Feature Delivery Step 5.3 -- App Bundle Splits (Android) Verify these splits are enabled in the AAB: - Language splits: only download user's language resources - Density splits: only download device's screen density assets - ABI splits: only download device's architecture native libs ============================================================ PHASE 6: OPTIMIZATION PLAN ============================================================ Generate a prioritized optimization plan sorted by savings: | # | Optimization | Current Size | After | Savings | Effort | Priority | |---|-------------|-------------|-------|---------|--------|----------| | 1 | {action} | {MB} | {MB} | {MB (%)} | {Low/Med/High} | {P0/P1/P2} | Top optimizations by typical impact: 1. Remove unused assets (0 effort, immediate savings) 2. Remove unnecessary ABI architectures (50%+ native lib savings) 3. Enable R8/ProGuard if not already (10-30% code size reduction) 4. Convert PNG -> WebP for photos (25-34% savings per image) 5. Subset fonts (50-80% savings per font file) 6. Enable resource shrinking (removes unused Android resources) 7. Replace heavy dependencies with lighter alternatives 8. Move large optional assets to on-demand resources ============================================================ SELF-HEALING VALIDATION (max 2 iterations) ============================================================ After producing output, validate data quality and completeness: 1. Verify all output sections have substantive content (not just headers). 2. Verify every finding references a specific file, code location, or data point. 3. Verify recommendations are actionable and evidence-based. 4. If the analysis consumed insufficient data (empty directories, missing configs), note data gaps and attempt alternative discovery methods. IF VALIDATION FAILS: - Identify which sections are incomplete or lack evidence - Re-analyze the deficient areas with expanded search patterns - Repeat up to 2 iterations IF STILL INCOMPLETE after 2 iterations: - Flag specific gaps in the output - Note what data would be needed to complete the analysis ============================================================ OUTPUT ============================================================ Write the full report to `docs/app-size-optimization-report.md` (create `docs/` if needed). ## App Size Optimization Report ### Current Size | Metric | iOS | Android | Target | |--------|-----|---------|--------| | Download size | {MB} | {MB} | < {target} MB | | Install size | {MB} | {MB} | < {target} MB | ### Size Breakdown | Category | Size | % of Total | Optimizable | |----------|------|-----------|-------------| | Native code | {MB} | {%} | {MB potential savings} | | Dart/JS code | {MB} | {%} | {MB potential savings} | | Images | {MB} | {%} | {MB potential savings} | | Fonts | {MB} | {%} | {MB potential savings} | | Native libraries | {MB} | {%} | {MB potential savings} | | Other assets | {MB} | {%} | {MB potential savings} | | Resources | {MB} | {%} | {MB potential savings} | | **Total** | **{MB}** | **100%** | **{MB total potential}** | ### Asset Audit Results | Issue | Files Affected | Current Size | Potential Savings | |-------|---------------|-------------|-------------------| | Unused images | {N} files | {MB} | {MB} (100%) | | PNG -> WebP | {N} files | {MB} | {MB} (~30%) | | Oversize images | {N} files | {MB} | {MB} | | Font subsetting | {N} files | {MB} | {MB} (~70%) | ### Code Optimization | Issue | Current | After | Savings | |-------|---------|-------|---------| | R8/ProGuard | {enabled/disabled} | enabled | {MB} | | Tree shaking | {enabled/disabled} | enabled | {MB} | | ABI filter | {all/filtered} | arm64-v8a only | {MB} | | Dead code | {N} unused items | removed | {MB} | ### Dependency Audit | Package | Size Contribution | Used % | Action | |---------|------------------|--------|--------| | {name} | {MB} | {%} | {keep/replace/remove} | ### Projected Size After Optimization | Metric | Current | After All Optimizations | Reduction | |--------|---------|------------------------|-----------| | Download | {MB} | {MB} | {%} | | Install | {MB} | {MB} | {%} | DO NOT: - Recommend removing features to reduce size -- find ways to deliver them efficiently. - Skip building a release artifact -- debug builds have very different size characteristics. - Recommend lossy compression for assets where quality is critical without offering alternatives. - Ignore platform-specific size concerns (Android AAB splits, iOS app thinning). - Report theoretical savings without verifiable measurements. - Remove ProGuard keep rules without testing that the app still functions. - Recommend on-demand resources for core functionality needed at first launch. NEXT STEPS: - "Implement the top 3 size optimizations and re-measure." - "Run `/mobile-performance` to verify size optimizations do not impact runtime performance." - "Run `/mobile-ci-cd` to add size budget checks to the CI pipeline." - "Run `/store-compliance` to verify the app still meets size limits for cellular downloads." ============================================================ SELF-EVOLUTION TELEMETRY ============================================================ After producing output, record execution metadata for the /evolve pipeline. Check if a project memory directory exists: - Look for the project path in `~/.claude/projects/` - If found, append to `skill-telemetry.md` in that memory directory Entry format: ``` ### /app-size-optimizer — {{YYYY-MM-DD}} - Outcome: {{SUCCESS | PARTIAL | FAILED}} - Self-healed: {{yes — what was healed | no}} - Iterations used: {{N}} / {{N max}} - Bottleneck: {{phase that struggled or "none"}} - Suggestion: {{one-line improvement idea for /evolve, or "none"}} ``` Only log if the memory directory exists. Skip silently if not found. Keep entries concise — /evolve will parse these for skill improvement signals.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.