Compose Mental Model & Phases Interview Questions
UI › Compose Core
In plain terms, what is recomposition, and what's the most common misconception junior engineers have about when and how often it runs?
What a strong answer covers: Recomposition is Compose re-invoking the composable functions whose tracked inputs changed, to produce an updated UI description; it is not a full-screen redraw or teardown, since Compose skips composables whose inputs are stable and unchanged. The common misconception is treating it like an expensive View invalidate that runs once per state change in a predictable top-to-bottom order, when in reality functions can run zero, one, or many times, in any order, and possibly for reasons unrelated to the specific state you changed.
A composable is recomposing far more than expected, and a teammate suggests wrapping the whole subtree in remember. Why is that often the wrong first move, and what would you actually check first?
What a strong answer covers: remember only caches a computed value across recomposition, it does nothing to stop recomposition from being triggered in the first place, so wrapping a whole subtree is usually a band-aid that hides the real cause. The first thing to check is whether the composable's parameters are actually inferred stable by the compiler, since Compose skips based on stability plus equality, not memoization; unstable collections from Java interop, mutable public vars, or lambdas that recreate an unstable capture are the usual culprits, and compose compiler reports or Layout Inspector's recomposition counts should be used to find that before reaching for remember.
Two composables look identical in code, but one recomposes needlessly on every parent recompose and the other doesn't, and the difference turns out to be how a lambda parameter is created. Walk me through why.
What a strong answer covers: If the lambda captures values from the enclosing scope, like an inline onClick = { viewModel.doThing(item) }, a new lambda instance is allocated on every recomposition unless the compiler can prove the captured values are stable, and even then older compiler behavior can treat the lambda's identity as changed, causing the child that receives it to recompose. Using a stable reference, a remembered lambda, or ensuring captured variables are themselves stable lets Compose treat the lambda as unchanged input and skip the child, tying back to the rule that stability is evaluated per parameter and a single unstable parameter defeats skipping for that call.