Recomposition & stability
Compose skips work when it safely can
Recomposition is Compose re-running a composable function to reflect new state. It's normal and expected β the problem is only when it happens more than necessary. Compose's optimization is to skip recomposing a composable entirely when all of its inputs are stable and equal to what they were last time.
A type is stable when Compose can trust that if an instance doesn't report a change, it hasn't changed β Int, String, and data classes of stable types all qualify. What defeats stability (and skipping) are things like: a lambda recreated on every call instead of remembered, a class with a public var Compose can't track, or a plain (non-@Stable/non-@Immutable) interface type.
remember { } caches a value across recompositions of the same composable instance, computing it only once (or when its keys change) instead of on every recomposition. derivedStateOf { } goes further: it derives a new value from other state, but only actually triggers recomposition of readers when the derived result changes β not every time the underlying state ticks. A GPS feed updating 10 times a second but a derivedStateOf that only flips from false to true once a walk crosses 1km means readers of that derived value recompose once, not ten times a second.