Status Update
Comments
no...@google.com <no...@google.com> #2
Can you try with the latest snapshot? Not reproducible for me on androidx-main.
to...@gmail.com <to...@gmail.com> #3
Ok, after trying a couple more versions, realized this is a duplicate of
From the release notes:
AndroidView's update callback's first invocation will now be defered until the view is attached, instead of running when the composition that introduces the AndroidView is applied. This fixes a bug where the update callback wouldn't be invalidated if a state it read was changed immediately by an effect. (Ie9438,
) b/291094055
Sorry for the confusion!
an...@google.com <an...@google.com>
an...@google.com <an...@google.com> #4
I tested the code you provided and agree the fling performance is not ideal, especially when you have a lot of text elements and item's height is so small. Prefetching logic is not helping much in such cases as we currently only prefetch one next item. You can try to combine multiple 2 or 3 rows into one item of LazyColumn to improve it a bit so the items height is not that small.
Please remember to always test the performance on release builds with the minification enabled. It is really important. I tested your sample in the release build and the scrolling works good enough, I also didn't notice any change in the performance when you run it with 1.0 of Compose and with 1.1-beta. With that I will make a conclusion that I didn't find a noticeable regression in Compose 1.1 and close this bug for now. Feel free to comment if you can share more useful information after testing on the release build.
to...@gmail.com <to...@gmail.com> #5
As said in first comment I do test in release mode.
And this is just a sample to show the issue easily by dropping frames on low end devices. This is not the grid item layout I use at all.
The problem is about fast fling start, in compose 1.0 there was no history pointers so very few events when performance was bad. Now all those are handled and cause the issue.
You need to repro on a low end device that will drop frames. On a P6P it's hard to trigger the issue and require a really fast fling with finger on screen for a long duration.
On a low end device a fast fling will just completely freeze until it start to settle. This never happens in 1.0.
I'll post later a video from my p3a that is quite slow those days and you'll see.
But there's clearly an issue somewhere.
ma...@google.com <ma...@google.com> #6
The problem is about fast fling start, in compose 1.0 there was no history pointers so very few events when performance was bad. Now all those are handled and cause the issue.
Please note that we don't use historical events to trigger scroll updates. We only account for those events in the velocity calculation so even if you drop a few frames - you get the right fling curve that feels natural. They should bring no overhead to the scroll itself.
to...@gmail.com <to...@gmail.com> #7
Please note that we don't use historical events to trigger scroll updates. We only account for those events in the velocity calculation so even if you drop a few frames - you get the right fling curve that feels natural. They should bring no overhead to the scroll itself.
I know the theory but that one was big change that could explain the issue from how things are acting. It of course can be a pure coincidence.
Here a video from P6P and P3A from a test app in release mode with R8 3.1.33 in full mode.
Both are the same APK with the exact same data, and with the image preloaded exactly the same.
As you can see on P3A that is not a very low end devices, this is barely usable and not shippable. Previously the P3A did not had such complete freeze and lags with 1.0. Even if in quite a few case the fling did not start.
On P6P since there's nearly never a dropped frame there's 0 issue with that "exponential" dropped frame triggering more dropped frames. With much more complex layouts, it's possible to reach the same state on the P6P where all blocks until some internals settles.
The repro here have 0 side code to be sure it was not caused by something else from my code like the fastscroll or the image loader or anything.
to...@gmail.com <to...@gmail.com> #8
So just to be 100% certain, I've removed the other parts of the app that require 1.1 and reverted to 1.0.4.
This is the video on the P3A with the exact same condition and type of flings, as you can see there's no match between those. (I did not reboot the P3A or kill other apps or did anything to the phone between the tries)
And the removed code is from completely other part so the code for this screen and everything related to this screen like image loader are 100% identical just 1.1.0 B1 vs 1.0.4.
Please reopen the issue and tell me what you need to investigate more, but you can't watch the 2 videos and tell me 1.1 works as expected.
an...@google.com <an...@google.com> #9
Is there a chance you can share the code of your app with me privately so I can reproduce it? I will not upload it anywhere or share with anyone else. If it is possible feel free to send it to my email andreykulikov@google.com, this will help with reproducing it.
Other thing you can help with is to try figure our in what release exactly it became broken - before 1.1.0-beta01 we had 6 alphas, if we can figure our what is the first alpha with such issue it could help us find the change causing that.
Thank you again for all your help, and sorry that I missed that you mentioned you are already testing on release build.
to...@gmail.com <to...@gmail.com> #10
I'll do a bisect on Compose versions tomorrow.
About the code I can share the actual layout and some stuff related to it, but it's a test project to play with Compose, so it's hard coded to connect to a private internal server with tons of data assumptions so you won't be able to actually use anything to see as no data.
an...@google.com <an...@google.com> #11
to...@gmail.com <to...@gmail.com> #12
Sent you a mail with a quick extract of most components used, it's not directly possible to build and use as missing a few things that are tied to nearly all the rest :(
The issue appeared on 1.1 beta 1. Tested alpha 4 / 5 and 6 and they work mostly like 1.0
ma...@google.com <ma...@google.com> #13
Thanks for a lot of info. While Andrey is investigating, could you please try to remove clickable from your grid items and try again with compose-1.1? We have a suspicion that clickable might have a performance regression when it enters the composition.
Thanks
to...@gmail.com <to...@gmail.com> #14
Yes removing clickable
from the image returns to normal performances.
BTW Since we talk about clickable and LazyColumn I still have not get any feedback on
ma...@google.com <ma...@google.com> #15
Amazing, thanks for trying. We're close to finding culprit, launching benchmarks now.
Could you please also try to use
val inputModeManager = LocalInputModeManager.current
Modifier.focusProperties { canFocus = inputModeManager.inputMode != InputMode.Touch }.focusable()
instead of clickable and see if issue is still there?
Cheers.
As for the other bug, we're on it investigating as well
to...@gmail.com <to...@gmail.com> #16
You mean replace : .clickable { onRowClick() }
by .focusProperties { canFocus = inputModeManager.inputMode != InputMode.Touch }.focusable()
?
ma...@google.com <ma...@google.com> #17
Yes. focus is the new part that we added in clickable in beta01 and it's a suspect for regression.
to...@gmail.com <to...@gmail.com> #18
So yes adding that instead of the clickable does bring back bad performance.
ma...@google.com <ma...@google.com> #19
Sweet! Thanks for the confirmation. We're on it, will report back when we have something to share.
an...@google.com <an...@google.com>
ra...@google.com <ra...@google.com>
ra...@google.com <ra...@google.com> #20
Status:
A Quickfix for this issue landed in
Working on a longer term fix which involves a major refactor, will land as multiple CLs. (Proof of concept in
ma...@google.com <ma...@google.com> #21
Our internal clients
We have added more benchmarks so we should catch such regressions ourselves in the future. Keep in mind that we intend to keep focusable inside the clickable modifier, which means that there's always be a small overhead of using it, but it should not cause user experience to suffer.
Thanks a lot tolriq
for pushing this regression through our radars, you made a difference. Let us know if you still see performance issues in this cases.
to...@gmail.com <to...@gmail.com> #22
Keep in mind that we intend to keep focusable inside the clickable modifier, which means that there's always be a small overhead of using it
What kind of overhead and how do they add up? Like a lazygrid of items that have a clickable on the whole item + 2 clickable icons. (And many on screen + scrolling fast)
- 1 clickable or 3 clickable in a single grid item is mostly the same
- it's *3
- it's ^4
- it's worse :)
Does it depends on layout hierarchy and could it worth it to not use clickable but a direct touch intercept on the items and manual handling when multiple click handler are necessary ?
About pushing I always push when I know I'm right, but unfortunately it's usually a lost cause with most team, glad it was not the case this time. So thanks for not ignoring the messages after the way too frequent "Won't Fix (Intended Behavior)"
I'll test with tomorrow release and report back if still an issue.
ra...@google.com <ra...@google.com> #23
The overhead is proportional to the number of clickables (Option 2 on your list). It does not depend on the hierarchy, but it is due to allocations and other housekeeping related to maintaining the focus tree. We are refactoring the focus modifiers right now which should reducing the number of objects and the amount of work done when focus nodes are attached/detached.
I think you should not intercept touch events directly as the current overhead will be greatly reduced after the refactor. The advantage to using Modifier.clickable is that you get keyboard/DPad support, accessibility, interaction state etc, which you don't if you directly intercept touch events.
The quick fix that will go out with the next release doesn't reduce the allocations, but just prevents propagation of onFocusChanged events if no one is observing them. Do let us know if you see the performance improvement, and we will get the long term fix out soon.
Thanks Tolriq
to...@gmail.com <to...@gmail.com> #24
Thanks for the details, will report back Thursday.
to...@gmail.com <to...@gmail.com> #25
Ok so glad to report that performance did improve a lot on P3a.
And all big lags have a corresponding:
2021-12-02 08:20:33.848 11681-11691/? I/xxx.xxxx: NativeAlloc concurrent copying GC freed 871792(30MB) AllocSpace objects, 476(9520KB) LOS objects, 66% free, 24MB/72MB, paused 102us,83us total 140.959ms
2021-12-02 08:20:35.383 11681-11691/? I/xxx.xxxx: NativeAlloc concurrent copying GC freed 716301(30MB) AllocSpace objects, 488(9760KB) LOS objects, 63% free, 27MB/75MB, paused 149us,215us total 265.249ms
2021-12-02 08:21:13.588 11681-11691/? I/xxx.xxxx: NativeAlloc concurrent copying GC freed 830994(31MB) AllocSpace objects, 515(10MB) LOS objects, 64% free, 26MB/74MB, paused 192us,120us total 236.436ms
2021-12-02 08:21:15.951 11681-11691/? I/xxx.xxxx: NativeAlloc concurrent copying GC freed 719208(27MB) AllocSpace objects, 509(10180KB) LOS objects, 64% free, 26MB/74MB, paused 247us,116us total 178.477ms
2021-12-02 08:21:17.237 11681-11691/? I/xxx.xxxx: NativeAlloc concurrent copying GC freed 685647(28MB) AllocSpace objects, 516(10MB) LOS objects, 65% free, 25MB/73MB, paused 118us,44us total 142.395ms
That should improve with next fix. Thanks for fix.
zo...@gmail.com <zo...@gmail.com> #27
st...@nambda.com <st...@nambda.com> #28
If so is there an ETA for the long term fix?
Thank you
ma...@google.com <ma...@google.com> #29
If 1.0.4 is only slightly better, than I have a doubt that the fix will help much, as it would be not related to focus.
Filing a separate bug with the some performance flame graphs attached and examples of the code you are running would help to understand the problem better.
Description
Jetpack Compose release version: 1.1 B1 Android Studio Build: AS 2021.1.1 B2 Kotlin version: 1.5.31
Create a default compose template app and use the code below
Fling on this will be insanely slow and miss tons of frames, we can see in the logs that items are composed multiple times and are restarted from earlier already dropped items. Like it will render items 1000 to 1300 then again the same range again and sometimes a third time.
With compose 1.0.4 there's no such issue and it works better. (But there's the fling that does not always works due to missing pointer history)
In my real apps this makes lazy column showing a lot of items really slow and unusable even in release mode R8 full mode and everything.