You can optimize specific packages by using R8 with packageScope. This is
designed as an optional first step for apps that don't yet use R8 and is not
recommended for apps that already use R8.
Consider whether to use packageScope
If your app already uses R8, don't use packageScope, because it is a
suboptimal configuration in terms of performance and app size. Instead, enhance
your app's R8 configuration with improved keep rules or, if using
compatibility mode, by migrating to R8's full mode.
For apps that don't yet use R8, but are adopting R8, use packageScope to
manage the transition incrementally. Because R8 applies powerful optimizations
that can alter app behavior, scoping these optimizations to specific packages
that are safe to optimize—such as AndroidX and Kotlin—lets you realize
performance gains with minimal risk. After your app is stable, you can gradually
expand these optimizations to the rest of your codebase and dependencies,
testing for stability at each stage.
Prerequisites
Using R8 with packageScope requires Android Gradle Plugin 9.0 or later.
Configure the optimization
To enable optimization with packageScope, complete the following steps.
Choose libraries to optimize
Identify the libraries to optimize. We recommend starting with the AndroidX and
Kotlin libraries androidx.**, kotlin.**, and kotlinx.** because these are
stable libraries that have been configured for R8 compatibility.
Enable support for using R8 with packageScope
Add the following to your project's gradle.properties file:
android.r8.gradual.support=true
Set up the optimization block
In your module-level build.gradle.kts (or build.gradle) file, add an
optimization block to your release build configuration. Inside this block, use
packageScope to list the specific packages you want to optimize. In your
build.gradle.kts file, wrap your package list in setOf().
Kotlin
android { buildTypes { release { proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),"proguard-rules.pro") optimization { enable = true packageScope = setOf("androidx.**","kotlin.**", "kotlinx.**") } } } }
Groovy
android { buildTypes { release { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' optimization { enable = true packageScope = ["androidx.**", "kotlin.**", "kotlinx.**"] } } } }
Test the optimization
After applying or updating the packageScope declaration, thoroughly test your
app to verify that no unexpected crashes or behavioral changes have
occurred.
Transition from optimizing specified packages to optimizing your entire app
To maximize optimization benefits, you should aim to gradually transition from
using packageScope to using R8 in your entire app. This process involves
incrementally expanding your optimization coverage:
- Start with stable libraries. Begin by only including widely used, stable
libraries that are compatible with R8's optimizations in the
packageScopelist. Start with the AndroidX and Kotlin librariesandroidx.**,kotlin.**, andkotlinx.**. - Incrementally add packages. Gradually add new package prefixes to the
packageScope:- Assess dependencies. Review your app's libraries. Good candidates to
add to the
packageScopelist include official Google libraries (for example,com.google.**) and other robust libraries likeOkHttp(for example,okhttp3.**andokio.**). Prioritize libraries that don't involve heavy reflection, serialization, or native code calls (JNI). - Prioritize based on package size. Use Android Studio's APK
Analyzer to identify the biggest contributors to your app size.
1. Build a release AAB or APK with R8 turned off.
1. Open it in the Analyzer and inspect the
dexfiles. 1. Sort packages by size. The largest packages offer the highest return on investment (ROI) for optimization. Targeting these first gives you the most significant size reduction early in the process, as long as these libraries don't have overly broad keep rules. See Choose libraries wisely for more information.
- Assess dependencies. Review your app's libraries. Good candidates to
add to the
- Verify behavior changes. After adding each new package prefix, conduct comprehensive testing to detect and resolve any regressions or unexpected behaviors.
- Add app packages last. If your app packages don't use a lot of
reflection, include the app packages in
packageScopeand add keep rules incrementally as needed. If your app packages use a lot of reflection, include the packages inpackageScopeand add package-wide keep rules for the required packages. Iterate over the keep rules to refine them. - Move to using R8 in your entire app. After the majority of your app's
dependencies are included in the
packageScopedeclaration and your app is stable, remove thepackageScopeto optimize your entire app in full mode.