09 September 2025
Posted by Johan Bay - Software Engineer
A small and fast app is key to a fantastic user experience. That's why we built R8, our app optimizer, which streamlines your app by removing unused code and resources, rewriting code to optimize runtime performance, and more.
With the release of version 8.12.0 of the Android Gradle Plugin (AGP), we're introducing optimized resource shrinking, an even better way to shrink your app with R8. By opting in, you can make your app smaller, which means smaller downloads, faster installations, and less memory used on your users' devices. The result is a faster startup, improved rendering, and fewer ANRs.
Resource shrinking for Android apps has been around for a long time, with several improvements made along the way– for instance, shrinking the resource table (resources.arsc) is now a default optimization.
The new approach improves resource shrinking by fully integrating it with the existing code optimization pipeline. In the new approach, R8 optimizes both code and resource references at the same time ensuring that all resources referenced exclusively from unused code are identified as unused and then removed. This completely eliminates the need for the unconditional keep rules generated by AAPT2 (the resource packaging tool for Android) and provides much more fine-grained and precise information for discarding unused code and resources
This is an improvement over the existing pipeline where code and resource optimization are separate. In the existing pipeline, AAPT2 generates keep rules to unconditionally keep classes referenced from resources. Then, R8 optimization runs with these keep rules. After R8 is done optimizing and shrinking the code, it scans the remaining code to build a graph of all the resources referenced directly or indirectly. However, the unconditional AAPT2 rules often keep code that is otherwise unused, which in turn causes R8 to keep both the unused code and the unused resources referenced by it.
First, turn on R8 optimization with resource shrinking, by using the following in your build.gradle.kts file:
android { buildTypes { release { isMinifyEnabled = true isShrinkResources = true … } } }
Turn on the new optimized resource shrinking pipeline by adding the following to your gradle.properties file:
android.r8.optimizedResourceShrinking=true
The optimized resource shrinking pipeline has shown significant improvements over the existing implementation. For apps that share significant resources and code across different form factor verticals, we measured improvements of over 50% in app size. Smaller apps see improvements as well – for example, in Androidify we see the following gains:
The table shows the progressive improvements in size as additional optimizations are enabled, from no shrinking to optimized resource shrinking. The cells marked with an asterisk (*) indicate improved numbers compared to the previous row. Enabling R8 trims the size of your DEX, while enabling resource shrinking removes unused resources in both the res folder and in the resource table, but does not change the DEX size further, and finally, optimized resource shrinking further reduces the size by removing both resources and DEX code since it can trace references across the DEX and resource boundary.
Starting with AGP 9.0.0, optimized resource shrinking becomes the standard behavior for any project that has the resource shrinker turned on.
Check out the newly updated documentation to try optimized resource shrinking and let us know if you encounter any problems on the issue tracker.