As a user, performance during interactions is one of the most important things in an application. We often complain about how slow an application is. However, developers say they have done the best they can. This is where Firebase Performance Monitoring is needed.

Firebase Performance Monitoring is a service that helps us to gain insight into the performance characteristics of our apps. Read this official documentation.

What you need to know

  • This will automatically measure app startup time, HTTP/S network requests, rendering data by screen and activity while in the foreground or background.
  • We can easily see performance metrics broken down by attributes, like country, device, app version and OS level.
  • Yes, we can create custom traces to capture our app’s performance in specific situations.
Firebase Performance Monitoring Dashboard

Automatic Traces

Firebase can detect when we have successfully added the SDK to our app when it receives event information like app interactions from our app.
The SDK batches events locally then send them to Firebase periodically or after the app goes to the background.
The report of performance data that capture between two points is called a trace.

  • App start trace
    measure the time between when the user opens the app and when the app is responsive. In the console, the trace’s name is _app_start

    ▶️ Starts when the app’s FirebasePerfProvider ContentProvider completes its onCreate method.
    ⏹ Stops when the first activity’s onResume() method is called.

  • App in background trace – measure the time when the app is running in the background. In the console, the trace’s name is _app_in_background

    ▶️ Starts when the last activity to leave the foreground has its onStop() method called.
    ⏹ Stops when the first activity to reach the foreground has its onResume() method called.

  • App in foreground trace – measure the time when the app is running in the foreground and available to the user. In the console, the trace’s name is _app_in_foreground

    ▶️ Starts when the first activity to reach the foreground has its onResume() method called.
    ⏹ Stops when the last activity to leave the foreground has its onStop() method called.

  • Screen trace – spans the lifetime of a screen and measures slow and frozen frames. In the console, screen traces are displayed in a separate table from other traces so that you can more easily investigate the performance of different screens in your app.

    ▶️ Starts for every Activity class when the app
    ⏹ Stops when the app calls onActivityStarted().Stops when the app calls onActivityStopped()

An HTTP/S network request trace will show us a report that capture any endpoint request from our app. This SDK will automatically collects metrics when we use Okhttp3 (specifically HTTP client v3.x.x), Java’s URLConnection and Apache HttpClient.

  • Response time — Time between when the request is made and when the response is fully received
  • Payload size — Byte size of the network payload downloaded and uploaded by the app
  • Success rate — Percentage of successful responses compared to total responses (to measure network or server failures)

For each request, Firebase checks if the network request’s URL matches a URL pattern. If matches Firebase will automatically aggregate the request’s data under the URL pattern. Which is not quite useful when our app using GraphQL to get data 😣 (or have I missed anything?)

Custom Traces

With custom trace, we can measure how long it takes our app to complete a specific task or set of tasks.

✔️ An app can have multiple custom traces
✔️ More than one custom trace can run at the same time
✔️ Names for custom trace, custom metrics, and custom attributes must meet the following requirements: no leading or trailing whitespace, no leading underscore characters, and max length is 32 characters.
import com.google.firebase.perf.FirebasePerformance;
import com.google.firebase.perf.metrics.Trace;

val trace = FirebasePerformance.getInstance().newTrace("test_trace")
trace.start()

// code that we want to trace

trace.stop()

Attribute

An attribute is a string value that helps us filter and segment data in the console. Performance Monitoring automatically logs the default attributes that are collected for any trace (app version, country, operating system information, device, radio, and carrier). And we can also add and monitor custom attributes. 

Limited to 5 custom attributes per trace.
import com.google.firebase.perf.FirebasePerformance;
import com.google.firebase.perf.metrics.Trace;

val trace = FirebasePerformance.getInstance().newTrace("test_trace")
trace.start()

// Update scenario.
trace.putAttribute("experiment", "A")

// Reading scenario.
val experimentValue = trace.getAttribute("experiment")

// Delete scenario.
trace.removeAttribute("experiment")

// Read attributes.
val traceAttributes = trace.attributes

trace.stop()

Metric

A metric is a numeric value that can be charted and measured over time. Further configure a custom trace to record custom metrics for performance-related events that occur within the trace’s scope.

import com.google.firebase.perf.FirebasePerformance;
import com.google.firebase.perf.metrics.Trace;

val trace = FirebasePerformance.getInstance().newTrace("test_trace")
trace.start()

// code that we want to trace (and log custom metrics)
val item = cache.fetch("item")
if (item != null) {
    trace.incrementMetric("item_cache_hit", 1)
} else {
    trace.incrementMetric("item_cache_miss", 1)
}

trace.stop()

@AddTrace

For android apps, performance monitoring support the @AddTrace annotation to create custom traces. The trace starts at the beginning of the specified method and stops when the method completes, including anything invoked by the method.

@AddTrace(name = "onCreateTrace", enabled = true /* optional */)
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
}

Disable Firebase Performance Monitoring

Disable for specific build variant at compile time. Add this following flag to our module (app-level) build.gradle

android {
  // ...
  buildTypes {
    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
      }
    }
  }
}

Disable for all build variants at compile time. Add the following flag to our gradle.properties file

// Set this flag to 'false' to disable @AddTrace annotation processing and
// automatic HTTP/S network request monitoring
// for all build variants at compile time.
firebasePerformanceInstrumentationEnabled=false

Disable at compile time, but to allow our app to enable it runtime. Add the following <meta-data> element to our app AndroidManifest.xml

<application>
    <meta-data
      android:name="firebase_performance_collection_enabled"
      android:value="false" />
</application>

Disable at compile time and do not allow our app to enable it runtime. Add the following <meta-data> element to our app AndroidManifest.xml

<application>
	<meta-data
	  android:name="firebase_performance_collection_deactivated"
	  android:value="true" />
</application>

Disable at runtime using Remote Config, simply just getBoolean("perf_disable") for the config.

FirebasePerformance.getInstance().isPerformanceCollectionEnabled = !config.getBoolean("perf_disable")

(Additional) Custom Trace

My friend @khairilushan create kotlin extension for add custom trace to simplify and cleaner way.

suggestion, only used for simple code

Leave a Reply

Your email address will not be published. Required fields are marked *


The maximum upload file size: 64 MB.
You can upload: image, audio, video, document, spreadsheet, interactive, text, archive, code, other.