Logo
Improve App Performance with Optimized Resource Shrinking in Android Gradle Plugin 8.12

Improve App Performance with Optimized Resource Shrinking in Android Gradle Plugin 8.12

By Sagar Maiyad  Sep 09, 2025

Google has released a game-changing feature in Android Gradle Plugin 8.12.0: optimized resource shrinking. This advancement can reduce app sizes by over 50% for apps with shared resources, making apps smaller, faster, and more efficient.

What is Resource Shrinking?

Resource shrinking is an Android build optimization that removes unused resources from your app's APK or AAB (Android App Bundle). This includes:

  • Unused images, layouts, and drawables
  • Alternative resources for different screen densities and configurations
  • Strings and other assets that aren't referenced by your code

Traditionally, resource shrinking has been a separate step from code optimization. But that's changing.

Resource Types That Can Be Removed

Resource Type Examples Typical Impact
Drawables PNG, JPEG, WebP, Vector drawables High (images are often largest)
Layouts XML layout files Medium
Strings Unused translations, labels Low-Medium
Colors/Themes Unused color definitions, styles Low
Raw Assets Fonts, audio, video files High (media files)
Alternative Resources hdpi, xhdpi, xxhdpi variants Very High (duplicates)

The Problem with Traditional Resource Shrinking

Until now, resource shrinking had a significant limitation: AAPT2 (Android Asset Packaging Tool 2) generated unconditional keep rules that prevented R8 from fully optimizing both code and resources together.

This meant:

  • Code that referenced unused resources couldn't be removed
  • Resources that were only used by unused code remained in the app
  • The optimization process wasn't as effective as it could be

Introducing Optimized Resource Shrinking

The new optimized resource shrinking approach, introduced in Android Gradle Plugin 8.12.0, solves this problem by fully integrating resource shrinking with code optimization in the R8 pipeline.

Traditional vs Optimized: Key Differences

Aspect Traditional Shrinking Optimized Shrinking
Processing Separate steps (code → resources) Unified R8 pipeline
AAPT2 Keep Rules Unconditional (blocks optimization) Eliminated (full optimization)
Accuracy Misses code-resource circular deps Detects all unused items
Size Reduction Moderate (20-30%) High (50%+ possible)
Build Time Baseline Comparable (slight increase)

How It Works

Instead of treating resource and code optimization as separate steps, the new system:

  1. Analyzes code and resources together in the R8 optimization pipeline
  2. Eliminates unconditional keep rules generated by AAPT2
  3. Identifies unused code and resources more precisely
  4. Removes both simultaneously for maximum efficiency

This holistic approach enables more aggressive optimization without compromising app functionality.

Impressive Performance Results

Google tested the new system on real-world apps, and the results are impressive:

Over 50% app size reduction for apps with shared resources

The Androidify sample app demonstrated significant improvements, showing how effective this optimization can be for production applications.

How to Enable Optimized Resource Shrinking

Step 1: Enable Minification and Resource Shrinking

First, ensure your release build has minification and resource shrinking enabled in your build.gradle file:

Kotlin DSL (build.gradle.kts):

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

Groovy (build.gradle):

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

Step 2: Enable Optimized Resource Shrinking

Add this line to your gradle.properties file:

android.r8.optimizedResourceShrinking=true

Step 3: Configure ProGuard Rules (If Needed)

Sometimes you need to keep specific resources that are referenced dynamically. Create or update proguard-rules.pro:

# Keep resources referenced by name at runtime
-keep class **.R$*
-keepclassmembers class **.R$* {
    public static <fields>;
}

# Keep specific drawable resources
-keep class **.R$drawable {
    public static final int splash_logo;
    public static final int app_icon_*;
}

# Keep all resources from a specific module
-keep class com.yourapp.core.R$* {
    *;
}

Step 4: Verify Configuration

Build your release APK/AAB and verify shrinking is active:

./gradlew assembleRelease --info

Look for log lines containing:

  • Shrinking resources
  • R8: Optimized resource shrinking enabled

That's it! Your app will now benefit from the optimized resource shrinking pipeline.

Advanced Configuration: Keep Files

For fine-grained control, create a res/raw/keep.xml file:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/legacy_screen,@drawable/brand_logo*"
    tools:discard="@layout/unused_*,@drawable/test_*" />

This allows you to:

  • Keep specific resources even if unused
  • Discard specific resources even if referenced (use with caution!)
  • Use wildcards (*) for pattern matching

What This Means for Your App

Smaller APK/AAB Sizes

Less storage space required on user devices and faster downloads, especially important for users on limited data plans.

Improved Installation Speed

Smaller app sizes mean faster installation times, reducing user drop-off during downloads.

Better Performance

Less code and fewer resources to load means faster app startup and improved runtime performance.

Reduced Bandwidth Costs

For developers distributing apps, smaller packages mean lower bandwidth costs and faster delivery.

When Does This Become Standard?

While currently opt-in via the Gradle property, optimized resource shrinking will become the default behavior in Android Gradle Plugin 9.0.0.

This gives developers time to:

  • Test the new optimization with their apps
  • Identify any edge cases or issues
  • Prepare for the transition before it becomes standard

Best Practices

1. Test Thoroughly

After enabling optimized resource shrinking, thoroughly test your app to ensure all necessary resources are retained and your app functions correctly.

2. Use ProGuard/R8 Rules Wisely

If you have custom ProGuard or R8 rules that explicitly keep resources, review them to ensure they don't conflict with the new optimization.

3. Monitor APK/AAB Size

Use Android Studio's APK Analyzer to examine your app before and after enabling the optimization to understand the impact.

Using APK Analyzer to Measure Impact

Step-by-Step Analysis

1. Build Two APKs:

# Build WITHOUT optimized shrinking
./gradlew assembleRelease

# Copy APK to backup
cp app/build/outputs/apk/release/app-release.apk app-before.apk

# Enable optimized shrinking in gradle.properties
echo "android.r8.optimizedResourceShrinking=true" >> gradle.properties

# Build WITH optimized shrinking
./gradlew clean assembleRelease
cp app/build/outputs/apk/release/app-release.apk app-after.apk

2. Open APK Analyzer:

  • In Android Studio: Build > Analyze APK...
  • Select your APK file

3. Compare Results:

You'll see a breakdown like this:

Before Optimization:

Total Size: 25.4 MB
├── res/           12.3 MB (48%)
│   ├── drawable/  8.1 MB
│   ├── layout/    2.2 MB
│   └── other/     2.0 MB
├── classes.dex    8.9 MB (35%)
├── lib/           3.2 MB (13%)
└── other/         1.0 MB (4%)

After Optimization:

Total Size: 13.8 MB (↓46%)
├── res/           4.2 MB (30%) ← Reduced by 66%
│   ├── drawable/  2.1 MB      ← Removed 6 MB
│   ├── layout/    1.0 MB      ← Removed 1.2 MB
│   └── other/     1.1 MB      ← Removed 0.9 MB
├── classes.dex    6.1 MB (44%) ← Reduced by 31%
├── lib/           2.8 MB (20%)
└── other/         0.7 MB (6%)

Key Metrics to Check:

  • res/ folder size - Should decrease significantly
  • classes.dex size - Dead code removal
  • Download size - What users actually download (AAB is compressed)

4. Check Resource References

Ensure resources are referenced directly in code rather than through string manipulation, which can make them appear unused to the optimizer.

5. Test on Multiple Configurations

Test your app on different device configurations to ensure resources for all screen densities and sizes are handled correctly.

Compatibility and Requirements

  • Minimum Version: Android Gradle Plugin 8.12.0
  • Build System: Compatible with both APK and AAB builds
  • R8: Requires R8 code shrinker (enabled by default in modern Android projects)

Example Impact: Androidify Sample App

Google demonstrated the optimization on the Androidify sample app, showing measurable size reductions. While specific numbers vary by app, the general pattern is:

Apps with many shared resources → Larger size reductions
Apps with minimal shared resources → Moderate size reductions

The key is that the optimization is intelligent—it only removes what's truly unused.

Troubleshooting Common Issues

Issue 1: App Crashes After Enabling Shrinking

Symptom: App crashes with Resources$NotFoundException

Cause: Resources loaded dynamically via string names are being removed

Solution:

// ❌ Bad: Dynamic resource loading (will be removed)
val resId = resources.getIdentifier("img_$category", "drawable", packageName)

// ✅ Good: Direct reference (won't be removed)
val resId = when(category) {
    "food" -> R.drawable.img_food
    "travel" -> R.drawable.img_travel
    else -> R.drawable.img_default
}

Or add to keep.xml:

<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@drawable/img_*" />

Issue 2: Resources Still Not Removed

Symptom: Expected resource reduction didn't happen

Possible Causes & Solutions:

  1. Minification not enabled:
// Must have BOTH enabled
isMinifyEnabled = true  // Required
isShrinkResources = true
  1. **Resources referenced in manifes

t:**

<!-- AndroidManifest.xml keeps these resources -->
<application android:icon="@drawable/ic_launcher" />
  1. Check build logs:
./gradlew assembleRelease --info | grep -i "shrink"

Issue 3: Build Fails After Enabling Optimization

Symptom: Build error: Resource shrinking failed

Solution: Check for:

  • Corrupted resource files (malformed XML)
  • Duplicate resource names across modules
  • Invalid keep.xml syntax
# Clean and rebuild
./gradlew clean
./gradlew assembleRelease --stacktrace

Issue 4: Specific Resources Missing in Production

Symptom: Some images/layouts work in debug but not release

Solution: Resources used only in debug builds need special handling:

// build.gradle.kts
buildTypes {
    debug {
        // Debug resources are kept automatically
    }
    release {
        // Explicitly keep debug-related resources if needed
        resValue("string", "debug_mode", "false")
    }
}

Or use tools:keep:

<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/debug_panel,@drawable/debug_*" />

Migration Tips

If you're currently using resource shrinking without the optimization:

  1. Upgrade to AGP 8.12.0 or higher
  2. Add the Gradle property to enable optimized shrinking
  3. Build your release APK/AAB and test thoroughly
  4. Compare app sizes before and after using APK Analyzer
  5. Monitor crash reports during initial rollout to catch any issues
  6. Test dynamic resource loading - Check all code that loads resources by name
  7. Verify all app features - Some resources may only be used in specific flows

The Technical Advantage

By integrating resource shrinking directly into the R8 pipeline, Google has eliminated a major bottleneck in app optimization. This unified approach allows for:

  • Dead code elimination that considers resource usage
  • Dead resource elimination that considers code references
  • Circular dependency resolution between code and resources
  • More accurate analysis of what's actually used

Looking Forward

Optimized resource shrinking represents a significant advancement in Android app optimization. As it becomes the standard in AGP 9.0.0, developers can expect:

  • Even smaller app sizes across the ecosystem
  • Faster app performance as a baseline
  • Better user experiences, especially on lower-end devices
  • Reduced storage pressure on user devices

Try It Today

With Android Gradle Plugin 8.12.0 available now, there's no reason not to test optimized resource shrinking. The potential for significant app size reduction makes it worth the effort.

For complete technical details and implementation guidance, read the full announcement by Johan Bay (Software Engineer) on the Android Developers Blog.


Have you tried optimized resource shrinking in your apps? Share your results with us on social media!

Android Performance Gradle

Author

Sagar Maiyad
Written By
Sagar Maiyad

Sagar Maiyad - Android Team Lead specializing in Kotlin, Jetpack Compose, Flutter, and Node.js development. Building practical Android apps with 2M+ downloads and sharing real-world development insights.

View All Posts →

Latest Post

Latest Tags