tezvyn:

How do you diagnose and fix excessive recomposition in Jetpack Compose?

Curated by the Tezvyn teamSource: developer.android.comadvanced
How do you diagnose and fix excessive recomposition in Jetpack Compose?

This tests your grasp of Compose's stability system. First, use Layout Inspector to find high-recomposition areas. Then, enable and analyze the Compose compiler report to diagnose unstable parameters (like List) or lambdas.

WHAT THIS TESTS: This tests your ability to apply a systematic, tool-driven approach to diagnosing non-trivial performance issues in Compose. It probes your understanding of the contract between your data types and the Compose compiler, which is the core of recomposition optimization. The interviewer wants to see that you can move beyond basic state management and debug the underlying stability model.

A GOOD ANSWER COVERS: A four-step strategy. First, use the Layout Inspector in Android Studio to visually identify which composables have a high recomposition count. This narrows the search space. Second, enable the Compose compiler metrics by adding the compiler argument in your Gradle file. Third, analyze the generated reports (class_stability.txt, composable.txt) to find unstable parameters or unskippable composables corresponding to the problem areas. Explain that unstable types, like a standard List, prevent skipping because the compiler can't guarantee their contents haven't changed. Fourth, explain lambda stability: a lambda that captures an unstable variable becomes unstable itself. A lambda that is re-allocated on every recomposition (e.g., { viewModel.onItemClick(it) }) is also considered unstable unless wrapped in remember.

COMMON WRONG ANSWERS: A major red flag is suggesting solutions without a diagnosis. For example, immediately saying "just wrap everything in remember" without first explaining how you would identify the actual problem. Another weak answer is only mentioning the Layout Inspector's recomposition counter without knowing the next step: using the compiler reports to find the root cause of why it's recomposing. Vaguely mentioning "immutability" without connecting it to specific unstable types like List or Map versus their kotlinx.collections.immutable counterparts is a sign of shallow knowledge.

LIKELY FOLLOW-UPS: How would you handle a class from an external library that you can't modify but is causing instability? (Answer: Create a stable wrapper class for it). When would you use the @Immutable or @Stable annotation, and what are the risks? (Answer: Use it when you can guarantee the contract; the risk is lying to the compiler, leading to subtle UI bugs where the UI doesn't update when it should). How does remember { { ... } } help with lambda stability? (Answer: It ensures the same lambda instance is passed across recompositions, making it stable as long as it doesn't capture unstable inputs).

ONE CONCRETE EXAMPLE: A ViewModel exposes val items: List<Item>. A parent composable passes this list to a child ItemList(items). The Layout Inspector shows ItemList recomposes every time anything in the parent's state changes, even unrelated state. The compiler report for ItemList shows its items parameter is unstable. The fix is to change the ViewModel to expose val items: ImmutableList<Item> using kotlinx.collections.immutable. This makes the parameter stable, allowing the compiler to mark ItemList as skippable and avoid unnecessary work.

Source: developer.android.com/jetpack/compose/performance/stability/diagnose

Read the original → developer.android.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.