Status Update
Comments
po...@google.com <po...@google.com>
ch...@google.com <ch...@google.com> #2
Triage notes: Still P3, still a real issue. Compat issue.
di...@gmail.com <di...@gmail.com> #3
Thanks for the context.
ro...@gmail.com <ro...@gmail.com> #4
Interesting, thanks for the explanation. If no solution can be provided, I think it would be good to have a disclaimer or warning on the official docs for this use case in
ke...@kraken.tech <ke...@kraken.tech> #5
I also couldn't find any mention about this and would love for it to be documented.
sh...@gmail.com <sh...@gmail.com> #6
any news about it? is it safe to use function to return state like this:
@Stable
abstract class ComposeViewModel<UiState, UiEvent> : ViewModel() {
@Composable
abstract fun uiState(): UiState
abstract fun onEvent(event: UiEvent)
}
ch...@google.com <ch...@google.com> #7
This issue is not about safety but about performance. It has always been safe to return a value from an @Composable
function. Examples of are remember
and CompositionLocal.current
which are both @Composable
.
This item is high on our backlog but has not yet been scheduled to an iteration.
sh...@gmail.com <sh...@gmail.com> #9
sorry for the missing details,
in terms of performance, what might be the impact when using a uiState
function in production app?
Any tips for debugging that scenario would be great:)
le...@google.com <le...@google.com> #10
in general any composable function that skips is about performance. but there are tradeoffs - it takes cpu cycles and memory to compare values and store them to determine if a function can be skipped. so for very small functions, a function skipping is probably a performance negative. and for very large functions, it has a positive impact (mostly). There are also cases where a function may never skip but is skippable (ie, any time its call site recomposes, a new value will be passed in). in this case skipping is nothing but a negative as you are wasting cpu cycles to compare and store which will never give you any benefit.
there are some implementation constraints that make value-returning composables harder to implement skipping for, but still possible. and on average we have observed that the value-returning composable functions are smaller, so not skipping them was considered largely a good trade-off.
We may introduce a way to opt-in some value-returning composables as skippable, but as chuck said we have got a lot of other things we are working on and this hasn't risen to the top of the list just yet.
al...@google.com <al...@google.com> #11
Triage notes, this also came up in a user study recently for a product similar to Molecule.
al...@google.com <al...@google.com> #12
Triage notes: Keep on backlog, this is something we'd like to do eventually.
al...@google.com <al...@google.com> #13
Triage notes: Still hard to justify for Compose UI since this would have a negative performance impact, even though this makes sense for Molecule. At a minimum it would need to be opt-in. Maybe the Molecule team would be interested in submitting a proposal/CL?
sh...@gmail.com <sh...@gmail.com> #14
Thank you for the detailed explanation on the trade-offs, I have a follow-up question regarding exposing a text field value as State versus returning it as a plain value (String) from a @Composable function in the ViewModel.
Key Question If my ViewModel exposes a text field's state via a @Composable function that returns a State<String> (e.g., mutableStateOf), I’ve noticed it reduces recompositions to only where the text field is directly consumed. This makes the updates more targeted and predictable.
On the other hand, if I expose it as a plain String, I’ve observed that the entire screen recomposes whenever the text field's value changes. While this might have a minor performance impact depending on the screen’s complexity, it simplifies the code as consumers don’t have to deal with State directly.
My questions are:
Is it considered best practice to consume the text field value as State (to minimize recompositions), especially when the screen contains multiple other components with their own state? Does returning a plain value (String) have a negligible performance impact that makes it acceptable in this case, and does it improve readability enough to justify the trade-off? For context, the screen also contains other components with their own independent state. These components may recompose more often than the text field itself, so I’m wondering if the reduced recompositions for the text field even matter in such cases.
Additional Clarification Needed Would also love to hear recommendations on where to dig deeper into Compose internals to better understand the trade-offs of these approaches (e.g., Compose skipping behavior, @Stable, mutableStateOf). Thanks again!
Description
Currently, a
@Composable
function that returns a value will never be skipped, even if it has immutable inputs and returns an immutable value.For use cases like modeling UI state in a presentation layer, a la Molecule , this would be a very useful optimization.
Example:
Whenever
selectedItemId
changes, I would wantcreateUiState
andcreateDetailsUiState
to recompose, but notcreateHeaderUiState
; none of its inputs have changed. Currently,createHeaderUiState
does recompose.