Optimizing Recomposition in Wear OS Compose
On a watch, sloppy state handling shows up fast as jank, extra work, and battery cost. The goal is not “zero recomposition”; it is keeping fast-changing state from invalidating more UI than necessary.
Recomposition is not the enemy
Compose is supposed to recompose when state changes. The problem starts when a small update, such as a timer tick or progress value, causes a much larger part of the watch screen to do work again.
On Wear OS that wasted work competes with a small battery, tight thermal limits, and short interaction windows. Optimize the scope of updates before reaching for clever caching.
Keep fast-changing state on a short leash
Split composables at real state boundaries and keep frequently changing values close to the UI that owns them. Stable immutable screen models also make it easier to see when a broad state object is invalidating more than intended.
Timers, progress indicators, sensor values, and animated state deserve extra attention because they can update repeatedly while the user is looking at the screen.
@Composable
fun CounterChip(count: Int, onIncrement: () -> Unit) {
FilledTonalButton(onClick = onIncrement) {
Text(text = count.toString())
}
}Measure on the watch you plan to support
A smooth emulator run does not tell you enough about a real watch. Profile the screens with the update patterns users will actually trigger and look for repeated work around text, timers, lists, and animations.
The best optimization is usually the boring one: make the state flow obvious, reduce the invalidation scope, and confirm the result on constrained hardware before adding complexity.