Improve Composable stabilities#2478
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2478 +/- ##
=======================================
Coverage 78.33% 78.33%
=======================================
Files 286 286
Lines 10432 10432
Branches 1500 1500
=======================================
Hits 8172 8172
Misses 1614 1614
Partials 646 646 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
JayShortway
left a comment
There was a problem hiding this comment.
Amazing! Thanks for doing this! 🙌 Just some questions.
| @Stable | ||
| @JvmSynthetic | ||
| @Composable | ||
| internal fun rememberButtonComponentState( |
There was a problem hiding this comment.
Just curious: do you think adding @Stable could theoretically introduce bugs, e.g. when it's not actually stable?
There was a problem hiding this comment.
Yes, theoretically, but in practice, it's not a common situation. Even when parameters are marked as @Stable, Compose ultimately determines skippability using the following equality checks:
- Unstable parameters are compared using instance equality (
===) - Stable parameters are compared using structural/object equality (
equals())
Additionally, Strong Skipping Mode is now enabled by default as of Kotlin 2.0.20. This mode enhances skipping behavior and was designed to be backward-compatible, minimizing the chance of introducing bugs even in existing projects.
So while misusing @Stable or @Immutable can theoretically lead to subtle issues, Compose’s internal safeguards and runtime checks reduce the likelihood of real world problems, especially for most common use cases.
https://developer.android.com/develop/ui/compose/performance/stability/strongskipping
There was a problem hiding this comment.
Thanks! Let's keep an eye out whether we see these subtle issues.
| @Stable | ||
| @JvmSynthetic | ||
| @Composable | ||
| internal fun rememberUpdatedStackComponentState( |
There was a problem hiding this comment.
We have a bunch more of these *ComponentStates. Did you try adding it to those as well? We have:
TextComponentStateImageComponentStateIconComponentStateCarouselComponentStateTabsComponentStateTimelineComponentState
There was a problem hiding this comment.
That's a great point. Thanks for bringing it up! I marked those components accordingly in 0a0870a, and I’ll continue refining and updating more in upcoming PRs.
📸 Snapshot Test648 unchanged
🛸 Powered by Emerge Tools |
**This is an automatic release.** ## RevenueCat SDK ### ✨ New Features * feat(purchases): Add setPostHogUserId() method to Purchases API (#2495) via Hussain Mustafa (@hussain-mustafa990) ### 🐞 Bugfixes * Improves button progress indicator size calculation. (#2485) via JayShortway (@JayShortway) ### 🔄 Other Changes * Revert "BC8 migration (#2477)" (#2501) via Toni Rico (@tonidero) * Add codelab instructions on README file (#2489) via Jaewoong Eum (@skydoves) * Use collectAsStateWithLifecycle instead of collectAsState in Compose (#2488) via Jaewoong Eum (@skydoves) * Improve Composable stabilities (#2478) via Jaewoong Eum (@skydoves) * [AUTOMATIC][Paywalls V2] Updates paywall-preview-resources submodule (#2486) via RevenueCat Git Bot (@RCGitBot) * BC8 migration (#2477) via Toni Rico (@tonidero) * Fixes building sample apps with SNAPSHOT dependencies (#2483) via JayShortway (@JayShortway) * [AUTOMATIC][Paywalls V2] Updates paywall-preview-resources submodule (#2484) via RevenueCat Git Bot (@RCGitBot) Co-authored-by: revenuecat-ops <ops@revenuecat.com>
…or increasing UI performances (#2608) ### Motivation This is a follow-up task from [#2478](#2478) Introduce runtime annotations library (which is completely [JVM-based annotations](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/runtime/runtime-annotation/src/commonMain/kotlin/androidx/compose/runtime/annotation/compose-runtime-annotation-documentation.md)) and add stability annotations on the purchase core models. ~Unfortunately, the AndroidX runtime annotations library requires a compile SDK version above 34. So for now, I’ve switched to using [compose-stable-marker](https://github.com/skydoves/compose-stable-marker) instead. It offers the exact same functionality, was created two years earlier than the official library, and is already widely adopted by many libraries and SDKs.~
Improve Composable stabilities by adding stability annotations to states, functions, and classes.
@Immutablewhen all public properties of a class are completely immutable typically for Kotlindataclasses representing domain models where the state never changes after creation.@Stablefor mutable types or interfaces with multiple implementations, as long as they provide consistent outputs for the same inputs, commonly used for UI state holders to enable optimized recomposition.Differences
Those below composable functions have been "Skippable" now from "Unskippable".