For the best user experience, you should optimize your app to make it as small and fast as possible. Our app optimizer, called R8, streamlines your app by removing unused code and resources, rewriting code to optimize runtime performance, and more. To your users, this means:
- Faster startup time
- Improved rendering and runtime performance
- Fewer ANRs
To enable app optimization, set isMinifyEnabled = true (for code optimization)
and isShrinkResources = true (for resource optimization) in your release
build's app-level build script as shown in the following code. We recommend
that you always enable both settings. We also recommend enabling app
optimization only in the final version of your app that you test before
publishing—usually your release build—because the optimizations increase the
build time of your project and can make debugging harder due to the way it
modifies code.
Kotlin
android { buildTypes { release { // Enables code-related app optimization. isMinifyEnabled = true // Enables resource shrinking. isShrinkResources = true proguardFiles( // Default file with automatically generated optimization rules. getDefaultProguardFile("proguard-android-optimize.txt"), ... ) ... } } ... }
Groovy
android { buildTypes { release { // Enables code-related app optimization. minifyEnabled true // Enables resource shrinking. shrinkResources true // Default file with automatically generated optimization rules. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') ... } } }
Optimize resource shrinking for even smaller apps
The 8.12.0 version of Android Gradle Plugin (AGP) introduces optimized resource shrinking, which aims to integrate resource and code optimization to create even smaller and faster apps.
Enable optimized resource shrinking
To turn on the new optimized resource shrinking pipeline for a version of AGP
before 9.0.0, add the following to your project's gradle.properties file:
android.r8.optimizedResourceShrinking=true
If you are using AGP 9.0.0 or a newer version, you don't need to set
android.r8.optimizedResourceShrinking=true. Optimized resource shrinking is
automatically applied when isShrinkResources = true is enabled in your build
configuration.
Verify and configure R8 optimization settings
To enable R8 to use its full optimization capabilities, remove the
following line from your project's gradle.properties file, if it exists:
android.enableR8.fullMode=false # Remove this line from your codebase.
Note that enabling app optimization makes stack traces difficult to understand, especially if R8 renames class or method names. To get stack traces that correctly correspond to your source code, see Recover the original stack trace.
If R8 is enabled, you should also create Startup Profiles for even better startup performance.
If you enable app optimization and it causes errors, here are some strategies to fix them:
- Add keep rules to keep some code untouched.
- Adopt optimizations incrementally.
- Update your code to use libraries that are better suited for optimization.
If you are interested in optimizing your build speed, see Configure how R8 runs for information on how to configure R8 based on your environment.
AGP and R8 version behavior changes
The following table outlines the key features introduced in various versions of the Android Gradle Plugin (AGP) and the R8 compiler.
| AGP version | Features introduced |
|---|---|
| 9.0 |
Optimized resource shrinking: Enabled by default (controlled using android.r8.optimizedResourceShrinking). Optimized resource shrinking helps integrate resource shrinking with the code optimization pipeline, leading to smaller, faster apps. By optimizing both code and resource references simultaneously, it identifies and removes resources referenced exclusively from unused code. This is a significant improvement over the previous separate optimization processes.This is especially useful for apps that share substantial resources and code across different form factor verticals, with measured improvements of over 50% in app size. The resulting size reduction leads to smaller downloads, faster installations, and a better user experience with faster startup, improved rendering, and fewer ANRs. Library rule filtering: Support for global options (for example, -dontobfuscate) in library consumer rules has been dropped, and apps will filter them out. For more information, see Add global options.Kotlin null checks: Optimized by default (controlled using -processkotlinnullchecks). This version also introduced significant improvements in build speed. For more information, see Global options for additional optimization.Optimize specific packages: You can use packageScope to optimize specific packages. This is in experimental support. For more information, see Optimize specified packages with packageScope.Optimized by default: Support for getDefaultProguardFile("proguard-android.txt") has been dropped, because it includes -dontoptimize, which should be avoided. Instead, use "proguard-android-optimize.txt". If you need to globally disable optimization in your app, add the flag manually to a proguard file.
|
| 8.12 |
Resource shrinking: Initial support added (Off by default. Enable using isShrinkResources). Resource shrinking works in tandem with R8 to identify and remove unused resources effectively.Logcat retracing: Support for automatic retracing in the Android Studio Logcat window. |
| 8.6 |
Improved retracing: Includes filename and line number retracing by default for all minSdk levels (previously required minSdk 26+ in version 8.2).Updating R8 helps ensure that stack traces from obfuscated builds are readily and clearly readable. This version improves how line numbers and source files are mapped, making it easier for tools like the Android Studio Logcat to automatically retrace crashes to the original source code. |
| 8.0 |
Full mode by default: R8 full mode provides significantly more powerful optimization. It is enabled by default. You can opt out using android.enableR8.fullMode=false.
|
| 7.0 |
Full mode available: Introduced as an opt-in feature using android.enableR8.fullMode=true. Full mode applies more powerful optimizations by making stricter assumptions about how your code uses reflection and other dynamic features. While it reduces app size and improves performance, it might require additional keep rules to prevent necessary code from being stripped.
|