Jetpack Compose
For Android engineers building Compose screens, this route connects state reads and rendering phases to list performance, gesture conflicts and regression checks. Start with the observable UI problem, then follow the relevant mechanism.
Free diagnostic tool
Compose compiler report reader: paste a release *-composables.txt locally to inspect function flags and parameter labels. Includes a sample, filters, and a summary. It does not upload reports or treat unstable parameters as failed performance tests. Start with the updated Strong Skipping guide.
Start with your question
| Question | Read first | What to inspect |
|---|---|---|
| Which phase runs after this state changes? | Composition, layout and draw phases | Where state is read and which scope is invalidated |
| Why does this LazyColumn stutter or recompose frequently? | LazyColumn scroll performance | Frame duration, build mode, stable keys, contentType and work per item |
| Why do taps, drags or nested scrolling conflict? | Gesture dispatch and nested scrolling | Input abstraction, consumption, coroutine keys and remaining scroll delta |
A practical reading order
- Use the three-phase model to identify where state is read. Recomposition counts alone are not a performance verdict.
- Inspect item identity, data changes and frame timing in a real LazyColumn. Record Compose and Kotlin compiler versions with measurements.
- Follow the gesture debugging workflow for competing taps and drags, then examine how nested scrolling distributes consumption.
- For system evidence, continue with Perfetto. For visual regressions, see Compose screenshot testing.
Core Articles
- Jetpack Compose recomposition performance: stability,
derivedStateOf, and skip behavior - Advanced Jetpack Compose applications and internals
- Jetpack Compose
Modifierinternals: from chained APIs toModifier.Node - Jetpack Compose gesture internals: from
pointerInputto the modifier node pipeline - Jetpack Compose animation internals: from
AnimationSpecto spring physics - Android Glance AppWidget internals: bridging Compose-style APIs to
RemoteViews - Compose and View interoperability: embedding
AndroidViewandComposeView
Layout, Drawing, and State Scope
- Jetpack Compose phases: from composition to layout and draw
- CompositionLocal internals: implicit data flow inside the composition tree
- Custom Compose layouts: from
MeasurePolicyto fixed measurement constraints - Compose Canvas custom drawing: from
DrawScopeto rendering details - Compose
LazyColumnscroll performance: from recomposition tracing to stable frame rate - Android Material 3 dynamic color: from Monet extraction to Compose theming
- Progressive Android Compose migration: from mixed View/Compose screens to declarative UI
- Compose screenshot testing without devices: Paparazzi and JVM rendering
- Compose for Wear OS: building declarative watch interfaces
Common Questions
- Why does this composable recompose so often?
- Should state be read in composition, layout, or draw?
- When is
rememberenough, and when do I needderivedStateOf? - How should a screen be split to avoid making every state change invalidate the whole tree?
- How do I migrate a View-based screen without losing lifecycle control or scroll behavior?
Next Step
If your Compose code relies heavily on Flow, StateFlow, and structured concurrency, continue with Kotlin and Coroutines.