Has anyone else noticed an their saved states incr...
# compose
k
Has anyone else noticed an their saved states increasing after converting to Compose? We recently started integrating Compose into our app, and the converted Fragment started triggering our checks preventing large saved state bundles (we used to have a problem with
TransactionTooLargeException
). Compose inflated our saved state by 3x for the Fragment! Kind of surprising given the functional, state-hoisting nature of Compose. I've done some investigating, and there is no smoking-gun culprit, just some inefficiencies (assuming their not required) that add up on complex screens. Findings in 🧵
👀 2
👌 2
2
1. CoreText saves a selectableId, even though the preceding comment block suggests it's deterministic across recompositions (and is also present when not in a SelectionContainer) 2. rememberSwipeableState saves the current value. But usages like Switch hoist that state using a change listener 3. The default key for lazy lists (DefaultLazyKey) is a Parcelable that just wraps an Int. Where the serialization contract for a Parcelable includes the fully qualified class name in UTF-16! 4. The default saveable key is `currentCompositeKeyHash` base-10 encoded, where there's a theoretical base-2^16 space available
l
Cc @Andrey Kulikov
d
@KoskiA can i ask you to share what check you use to detect such things?
a
Thanks for the analysis! 1. As far as I understand the implementation in CoreText, the idea is that the value stays the same when it is used inside LazyColumn, for example. but agree that we can optimize it to not have a value when there is no selection/selectioncontainer. Filed https://issuetracker.google.com/issues/192459829. 2. Fixed already in Switch - https://android-review.googlesource.com/c/platform/frameworks/support/+/1742195. rememberSwipeableState() in general is experimental and we plan to reevaluate it for 1.1 to see in what cases state restoration is needed 3. Yeah, it is tricky. We can’t just use ints as it could collide with the user provided keys in cases when the user provided keys for some items and didn’t provide for others. Filed https://issuetracker.google.com/issues/192460434 to explore if we can optimize it for safe cases 4. I experimented, and seems like we indeed can use
currentCompositeKeyHash.toString(36)
here. 36 is the largest supported radix. this shortens keys like 1634082918 into r0w2g6. Filed https://issuetracker.google.com/issues/192458970
👍 1
🙏 2
👍🏼 1
k
We register
Application.ActivityLifecycleCallbacks
and
FragmentManager.FragmentLifecycleCallbacks
, and manually write the save state
Bundle
to a
Parcel
and call
Parcel.dataSize()
. We also crawl the bundle values to print detailed break-downs
👍 1
Hey @Andrey Kulikov I've been following those bugs; thanks for getting these addressed so quickly! We can expect the fixes in the next RC correct? Or is there some branching strategy at play?
a
unfortunately they will not be merged in 1.0. as RC was cut already it was branched into a separate release branch and we only cherrypick critical issues there. in our main branch we currently work on alpha of 1.1 already
🙏 1
👍 1