Performance monitoring lets you measure what matters — startup time, screen load time, network latency — in the field across millions of real devices and network conditions.
Firebase Performance Monitoring
Automatic Instrumentation
Firebase Performance automatically measures:
- App start time (cold/warm/hot)
- HTTP/S network requests (latency, payload size, success rate)
- Foreground/background session duration
Custom Traces
Measure any specific operation:
// Simple trace
val trace = Firebase.performance.newTrace("article_render")
trace.start()
// ... load and render article
val article = repository.getArticle(id)
renderArticle(article)
trace.stop()
// With custom metrics and attributes
val trace = Firebase.performance.newTrace("search_query")
trace.putAttribute("query_length", query.length.toString())
trace.start()
val results = search(query)
trace.putMetric("result_count", results.size.toLong())
trace.stop()
Measuring Screen Load Time
class ArticleDetailViewModel @Inject constructor(
private val repository: ArticleRepository,
private val perf: FirebasePerformance
) : ViewModel() {
private var loadTrace: Trace? = null
fun startLoad() {
loadTrace = perf.newTrace("article_detail_load").also { it.start() }
}
fun loadArticle(id: String) = viewModelScope.launch {
startLoad()
try {
val article = repository.getArticle(id)
_state.value = UiState.Success(article)
loadTrace?.putAttribute("source", "network")
} catch (e: Exception) {
loadTrace?.putAttribute("error", e.javaClass.simpleName)
_state.value = UiState.Error(e.message ?: "")
} finally {
loadTrace?.stop()
}
}
}
HTTP Monitoring Override
// OkHttp interceptor for custom performance monitoring
class PerformanceInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val metric = Firebase.performance.newHttpMetric(
request.url.toString(),
FirebasePerformance.HttpMethod.GET
)
metric.start()
val response = chain.proceed(request)
metric.setHttpResponseCode(response.code)
metric.setResponsePayloadSize(response.body?.contentLength() ?: -1)
metric.stop()
return response
}
}
Systrace / Perfetto: Deep Analysis
For frame-level analysis that Firebase can't provide:
# Record a Perfetto trace while reproducing a jank issue
adb shell perfetto \
-o /data/misc/perfetto-traces/trace.perfetto-trace \
-t 10s \
"track_event,view,gfx,input,sched,power"
# Pull the trace
adb pull /data/misc/perfetto-traces/trace.perfetto-trace
# Open at ui.perfetto.dev
Android StrictMode: Catch Issues in Development
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.penaltyDeath() // crash in DEBUG so you can't miss it
.build()
)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.detectActivityLeaks()
.penaltyLog()
.build()
)
}
}
}
App Startup Tracing (Jetpack App Startup)
// Measure initialization order and duration
class AnalyticsInitializer : Initializer<Unit> {
override fun create(context: Context) {
val trace = Firebase.performance.newTrace("analytics_init")
trace.start()
Analytics.initialize(context)
trace.stop()
}
override fun dependencies(): List<Class<out Initializer<*>>> = emptyList()
}
Rendering Performance
// Compose: measure recomposition count in debug builds
@Composable
fun ArticleList(articles: List<Article>) {
RecompositionCounter("ArticleList") // custom debug composable
LazyColumn { /* ... */ }
}
// Report slow frame rate to analytics
class FrameRateMonitor(private val analytics: Analytics) {
fun onFrameRendered(durationMs: Long) {
if (durationMs > 16) { // > 60fps threshold
analytics.logEvent("slow_frame") {
param("duration_ms", durationMs)
param("screen", currentScreen)
}
}
}
}
Key Takeaways
| Tool | What it measures | When to use |
|---|---|---|
| Firebase Performance | App start, network, custom traces | Production-wide field data |
| Android Vitals | Crash rate, ANR, slow renders | Play Console; affects store ranking |
| StrictMode | Disk/network on main thread, leaks | Debug builds only |
| Perfetto/Systrace | Frame-level janks, scheduler events | Reproducing specific jank bugs |
| Custom traces | Your specific flows (checkout, search) | Measure what matters to your business |