Firebase Performance Plugin causing slow build time
Firebase Performance has released a new version of perf-plugin
(v1.3.0). This would enable disabling the Firebase Performance Monitoring Gradle plugin for a specific build variant (including buildTypes or productFlavors).
An example below:
android {
// ...
debug {
FirebasePerformance {
// Set this flag to 'false' to disable @AddTrace annotation processing and
// automatic HTTP/S network request monitoring
// for a specific build variant at compile time.
instrumentationEnabled false
}
}
}
Reference to release notes:
https://firebase.google.com/support/release-notes/android#2019-07-10
Firebase in our project caused 40% build time increase. To speed up debug builds we added a possibility to switch it on/off using build parameters in app/build.gradle and root build.gradle files:
app:
if (!project.hasProperty("disable-performance-plugin")) {
apply plugin: 'com.google.firebase.firebase-perf'
}
root/buildscript/dependencies:
if (!project.hasProperty("disable-performance-plugin")) {
classpath('com.google.firebase:firebase-plugins:1.1.5') {
exclude group: 'com.google.guava', module: 'guava-jdk5'
}
}
when running from the command line use
./gradlew your-task -Pdisable-performance-plugin
when working from Android Studio, add the flag to compiler options:
All of the existing answers are valid, but they all miss something.
To deal with this issue, you have 2 major options to choose from.
1. Use firebasePerformanceInstrumentationEnabled
property
This is the official way provided by the SDK itself to disable it during the build process.
What this does:
- Reduces
transformClassesWithFirebasePerformancePluginFor*
task execution time to ~5-10s. - Disables automatic traces and request monitoring, but leaves custom traces enabled. You can control the latter with AndroidManifest
<meta-data>
tags and calls toFirebasePerformance.getInstance().setPerformanceCollectionEnabled()
. More info in the docs.
How to do this:
I think it's much easier to only enable plugin in those rare cases when we need it (usually it will be only when we publish the app) rather than disable it in all other cases.
Note: Of course, with manual builds you might forget to enable it. So if you don't have CI, it might be worth adding some other automatic scripting in Gradle, or sticking to the opposite approach that is used in other answers.
In general though, we only need two steps:
Add the following line to
gradle.properties
file:firebasePerformanceInstrumentationEnabled=false
Use the following command in your CI config or manual builds:
./gradlew assembleRelease -PfirebasePerformanceInstrumentationEnabled=true
Pros:
- Only one property to set up.
Cons:
- Plugin still adds additional ~5-15s to the build time.
2. Use custom Gradle project property to avoid applying firebase-perf
Gradle plugin
What this does:
- transformClassesWithFirebasePerformancePluginFor* task is not executed at all. Also we save some additional ~5–10s overhead that is present when using the first solution.
- Same as the first method – disables automatic traces and request monitoring, but leaves custom traces enabled. You can control the latter with AndroidManifest
<meta-data>
tags and calls toFirebasePerformance.getInstance().setPerformanceCollectionEnabled()
. More info in the docs.
How to do this:
This approach has similar points and warnings, and also includes two steps:
Modify your app module's
build.gradle
file:if (project.hasProperty('useFirebasePerf')) { apply plugin: 'com.google.firebase.firebase-perf' }
Note: you don't need to apply the same check to your project-level
build.gradle
:classpath "com.google.firebase:firebase-plugins:$firebase_plugins_version"
This declaration won't be used in any way by Gradle when the plugin itself is not enabled.
And you don't need to exclude
guava-jdk5
dependency there, if you're using firebase-plugins v1.1.1 or later as stated in the docs.Use the following command in your CI config or manual builds:
./gradlew assembleRelease -PuseFirebasePerf
Pros:
- Completely eliminates time expenses associated with Firebase Performance Gradle plugin.
Cons:
- Introduces conditional check for applying plugin in your Gradle script, some might argue that it's not an idiomatic approach.
* (Bonus option) Use custom Gradle project property to exclude firebase-perf
SDK
If you don't use custom traces or any other features from Firebase Performance SDK and only rely on automatic monitoring (that is, you don't have any dependencies on SDK in your code), then you can exclude this dependency for non-production builds.
How to do this:
All you need to do is update your app module's build.gradle
file:
If you chose to use the first option, then change your dependency like this:
if (project.property('firebasePerformanceInstrumentationEnabled') == 'true') { implementation "com.google.firebase:firebase-perf:${firebase_perf_version}" }
If you chose the second one:
if (project.hasProperty('useFirebasePerf')) { implementation "com.google.firebase:firebase-perf:${firebase_perf_version}" }
Advantage:
- This might save you some additional ~5-10s, spent on configuring dependency and "ProGuarding" it.
Drawbacks:
- Your production APK size will be larger than debug one by ~0.5mb. This might disrupt your reports or predictions, so you need to be aware of it.
- If you were close to surpassing 64K method count limit, you might suddenly step over it on production builds and find yourself in the MultiDex zone. And that means extra work to do and tests to run. All because Firebase Performance brings a formidable number of almost 5K method references (after applying ProGuard with optimizations).
You can also check out my article where I expand a bit more on this topic.