Reputation: 1232
I'm encountering an issue with Jetpack Compose where recomposition seems inefficient when using a when statement, even though the resulting composable is the same. Here are the simplified examples:
Example 1: Triggers Recomposition
when (theme) {
ThemeOption1 -> MyComposable(content = content)
ThemeOption2 -> MyComposable(content = content)
}
In this example, switching between ThemeOption1 and ThemeOption2 causes recomposition, even though the same composable MyComposable is being used in both branches.
Example 2: Does Not Trigger Recomposition
when (theme) {
ThemeOption1,
ThemeOption2 -> MyComposable(content = content)
}
In this example, grouping the when conditions to lead to the same composable prevents unnecessary recompositions.
Question: Why does Jetpack Compose not recognize that both branches of the when statement in the first example lead to the same composable and thus trigger recomposition? Is there a way to make Compose smarter in this regard or is this a limitation by design?
Additional Context: The theme variable is a state observed by the composable. The content of MyComposable does not change between different theme options. Any insights or recommendations to optimize this scenario in Jetpack Compose would be greatly appreciated. Thank you!
Upvotes: 1
Views: 60
Reputation: 15579
That's by design and it is a necessity to ensure correctness, not an arbitrary limitiation.
Although both MyComposable(content = content)
from the first example look the same they actually aren't: They are two separate composables in the compose tree. This becomes relevant if you take into account that each composable can have an internal state represented by what they remember
ed on previous recompositions.
Let's assume MyComposable
looks like this (for brevities sake I ignored the content
):
@Composable
fun MyComposable(content: @Composable () -> Unit) {
var counter by remember { mutableStateOf(0) }
counter++
Text("$counter")
}
With this your Example 1 and Example 2 will produce a different output. Whenever MyComposable
is called counter
is incremented: In the second example this will be done for either ThemeOption1
or ThemeOption2
, in the first example, however, you have two different counters, one that counts for ThemeOption1
, the other that counts ThemeOption2
.
So doing the additional recomposition that you found redundant actually is essential. It wouldn't be possible to accurately update the counters otherwise.
Upvotes: 2