Android Performance and Stability
Start with slow startup, dropped frames or a WebView renderer exit. Define the symptom before collecting evidence; each route below leads to concrete tool steps and a way to verify the result.
Choose a debugging route
| Symptom | Read first | Next action |
|---|---|---|
| Slow startup with unclear first-frame and usable-screen metrics | TTID, TTFD and startup benchmarks | Fix the startup conditions, then inspect the critical path in Perfetto |
| Jank without a usable trace or a clear explanation | Getting started with Perfetto | Reproduce the issue and inspect the main thread, scheduling and frame timing |
| A blank WebView or a renderer-exit callback | WebView renderer crashes and recovery | Separate exit signals from causes and verify destruction and recreation |
| A Compose list scrolls poorly | LazyColumn performance debugging | Use a release build and examine item identity, state reads and frame duration |
From a metric to a regression check
- Define startup metrics: separate cold, warm and hot starts, and distinguish first frame from usability.
- Capture and read a Perfetto trace: map a user action to thread work and waiting time.
- Change one evidence-supported bottleneck while preserving the device, dataset, build type and capture conditions.
- Repeat measurements with Macrobenchmark. Compare distributions and check for regressions.
- For a renderer exit, follow the WebView stability workflow. A performance trace alone does not establish a crash cause.
Core Articles
- Android startup optimization: from Zygote fork to first frame with Perfetto
- Android app startup optimization: metrics, paths, tools, and governance
- RecyclerView cache internals: four cache levels, reuse, and Prefetch
- Android Bitmap memory model: Java heap, native heap, and Hardware Bitmap
- Android RenderThread and HWUI: rendering pipeline, DisplayList, and jank analysis
- Android rendering and graphics stack: View, HWUI, and SurfaceFlinger
- Android Perfetto and Systrace: system-level performance analysis
- Android Perfetto tracing: ftrace, TrackEvent, and production-grade performance monitoring
- Android audio system: AudioFlinger, mixing policy, and AAudio low latency
- Android Macrobenchmark in practice: startup, scrolling, and performance regression testing
Runtime, Memory, and Graphics Performance
- Android ART garbage collection internals
- Android ART dex2oat: from DEX bytecode to OAT machine code with AOT/JIT compilation
- Android native memory analysis: from malloc_debug to heapprofd
- Android Vulkan rendering: from OpenGL ES migration to GPU driver tuning
- Android power management: from WakeLock misuse to Doze-mode engineering
- Android AlarmManager scheduling: Binder calls, AlarmManagerService, and exact wakeups under Doze
- Android DEX bytecode and MultiDex loading
- Android Media3 playback architecture: from ExoPlayer to MediaSession
- Android networking stack: from DNS to HTTP/3 QUIC
- Android font rendering: Typeface loading and Skia glyph rasterization
Performance Debugging Framework
- Define the metric first: P50, P90, P99, first frame, dropped frames, memory peak.
- Collect evidence: Perfetto trace, logs, ANR trace, heap dump, benchmark results.
- Break down the path: main thread, Binder, I/O, rendering, GC, scheduling.
- Verify the fix: local benchmarks, staged monitoring, and regression gates.
Next Step
If the performance issue is tied to UI state updates, continue with Jetpack Compose Deep Dives. If the bottleneck involves model inference, NPU scheduling, power, or thermal behavior, go to Android On-device AI. If the issue comes from builds, tests, or release pipelines, go to Mobile Engineering.