Aaron Waller
10/04/2022, 6:17 AMczuckie
10/04/2022, 7:31 AMZoltan Demant
10/04/2022, 8:18 AMZoltan Demant
10/04/2022, 8:26 AMFlow<T>
(or subclasses) to a bunch of composable functions in your codebase? In terms of skippability, its identical to passing List<T>
(which is also unstable). This article has awesome details about skippability and how you can find out if your composables are skippable or not 🙂Aaron Waller
10/04/2022, 8:27 AMZoltan Demant
10/04/2022, 8:42 AMFlow.collectAsState()
does exactly that. Maybe drop a comment on the article about it?qlitzler
10/04/2022, 9:11 AMIn terms of skippability, its identical to passingJust a note about this: You can use kotlin collections(which is also unstable).List<T>
ImmutableList<T>
to male it stable
. It’s not much of a hassle and it works well.Ben Trengrove [G]
10/04/2022, 4:15 PM@Composable
fun MyComp(viewState: Flow<ViewState>) {
val state = viewState.collectAsState()
LazyColumn {
items(state.items) {}
}
}
Sure, MyComp wouldn't be skippable but that doesn't matter as it's not the bit of state that is changing. The bit that is recomposing is the list, you would be more concerned about the stability of your items class as that will determine if your whole LazyList recomposes or just the row.
+1 on measuring these things, not just blindly following best practices. We always say "tools not rules" when it comes to performance. You can write a benchmark to measure the performance and then test out that your changes are actually helping. https://medium.com/androiddevelopers/inspecting-performance-95b76477a3d7
I would also add my article on Stability to the list of reading.
https://medium.com/androiddevelopers/jetpack-compose-stability-explained-79c10db270c8Daniele Segato
10/04/2022, 5:03 PMqlitzler
10/04/2022, 5:06 PM@Stable / @Immutable
annotationsqlitzler
10/04/2022, 5:10 PMList
is stable. Either by using the annotations, or by using immutable collections.
This way the LazyList
can ke skipped during the recomposition phase.
Example:
@Composable
fun ImmutableList<T>.Compose() {
LazyList {
...
}
}
⬆️ Optimised (skippable)
@Composable
fun List<T>.Compose() {
LazyList {
...
}
}
⬆️ Unoptimised (not skippable)Daniele Segato
10/04/2022, 5:17 PMqlitzler
10/04/2022, 5:23 PM@Compose
method which depends on a Flow<>
, for example with flow.collectAsState()
, would not be stable and hence skippable, but that’s ok.
data class StableItem(val string: string)
// Unskippable, but it doesn't matter performance wise
@Composable
fun Flow<ImmutableList<StableItem>>.Screen() {
val list = collectAsState()
list.value.List()
}
// Skippable
@Composable
fun ImmutableList<StableItem>.List() {
LazyList {
items(this) { it.Cell() }
}
}
// Skippable
@Composable
fun StableItem.Cell() {
Text(string)
}
Ben Trengrove [G]
10/04/2022, 5:25 PMDaniele Segato
10/04/2022, 5:26 PMBen Trengrove [G]
10/04/2022, 5:28 PMDaniele Segato
10/04/2022, 5:34 PMBen Trengrove [G]
10/04/2022, 5:38 PMDaniele Segato
10/04/2022, 5:41 PMqlitzler
10/04/2022, 5:45 PMBen Trengrove [G]
10/04/2022, 6:07 PMqlitzler
10/04/2022, 6:38 PM