Fixed
Status Update
Comments
gs...@gmail.com <gs...@gmail.com> #2
cl...@google.com <cl...@google.com>
an...@google.com <an...@google.com> #3
Yes, it is definitely recommended to use loadImageResource as loading large images on the ui thread will always make the scrolling laggy. Just to confirm, could you please try the same but without image at all? Without calling imageResource and Image. maybe just replace it with
Box(modifier = imageModifier.background(Color.Gray))
I am curious if the scrolling will still be laggy in such case
Box(modifier = imageModifier.background(Color.Gray))
I am curious if the scrolling will still be laggy in such case
gs...@gmail.com <gs...@gmail.com> #4
I have tried with loadImageResource and with the Box you suggested and its still laggy hmm
I have also tried the codelab for the state tutorial (the add tasks codelab) and it only shows an icon and a Text as a row and is also choppy if we scroll
thanks for the feedback
I have also tried the codelab for the state tutorial (the add tasks codelab) and it only shows an icon and a Text as a row and is also choppy if we scroll
thanks for the feedback
ap...@google.com <ap...@google.com> #5
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 17cd20811cfd5df0dceb95706d76248f2f7f2e42
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Tue Sep 22 20:09:35 2020
Scroll performance optimization for LazyColumnFor/LazyRowFor
We were unnecessary recomposing all the visible items on every scroll offset if the items type was not stable(if it was stable the recomposition was skipped using the regular runtime logic). In this change I introduced the itemContent lambda caching logic which allows to reuse the same lambda instance for not changed items. If we pass the same lambda instance into subcomposition the runtime will skip the whole composition as there is nothing to recompose. We clear this cache if the new itemContentFactory was provided or if the parent constraints have been changed.
Bug: 168293643
Bug: 167972292
Bug: 165028371
Relnote: Performance optimizations for LazyColumnFor/LazyRowFor scrolling by not doing unnecessary recompositions during every scroll
Test: tested manually and with a new test for both LazyColumnFor and LazyRowFor. Instead of 18 recompositions for each item for a simple scroll we do none of them.
Change-Id: I64f6568fd1193a6d28e3e2e2205b977f4a5f116b
M compose/foundation/foundation/api/current.txt
M compose/foundation/foundation/api/public_plus_experimental_current.txt
M compose/foundation/foundation/api/restricted_current.txt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnForTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowForTest.kt
A compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/CachingItemContentFactory.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyFor.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyForState.kt
https://android-review.googlesource.com/1434551
Branch: androidx-master-dev
commit 17cd20811cfd5df0dceb95706d76248f2f7f2e42
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Tue Sep 22 20:09:35 2020
Scroll performance optimization for LazyColumnFor/LazyRowFor
We were unnecessary recomposing all the visible items on every scroll offset if the items type was not stable(if it was stable the recomposition was skipped using the regular runtime logic). In this change I introduced the itemContent lambda caching logic which allows to reuse the same lambda instance for not changed items. If we pass the same lambda instance into subcomposition the runtime will skip the whole composition as there is nothing to recompose. We clear this cache if the new itemContentFactory was provided or if the parent constraints have been changed.
Bug: 168293643
Bug: 167972292
Bug: 165028371
Relnote: Performance optimizations for LazyColumnFor/LazyRowFor scrolling by not doing unnecessary recompositions during every scroll
Test: tested manually and with a new test for both LazyColumnFor and LazyRowFor. Instead of 18 recompositions for each item for a simple scroll we do none of them.
Change-Id: I64f6568fd1193a6d28e3e2e2205b977f4a5f116b
M compose/foundation/foundation/api/current.txt
M compose/foundation/foundation/api/public_plus_experimental_current.txt
M compose/foundation/foundation/api/restricted_current.txt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnForTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowForTest.kt
A compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/CachingItemContentFactory.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyFor.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyForState.kt
ap...@google.com <ap...@google.com> #6
Project: platform/frameworks/support
Branch: androidx-master-dev
commit dc602125a9e5fc15a37ba4fa7610998a94ead29f
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Fri Sep 25 21:14:09 2020
Do less work in SubcomposeLayout when subcompose called with the same lambda
If the lambda object for the slot didn't change and there were no pending recompositons we can skip the whole subcompositions invocation as it will result in unchanged tree. Starting subcomposition is a heavy weight operation so this change allows to improve the measure benchmarks for LazyColumn scrolling by 88 percents.
To achieve it I added a hasPendingChanges() method for Composition class.
Bug: 168293643
Bug: 167972292
Bug: 165028371
Relnote: The scrolling performance of LazyColumn/Row is improved by doing less work in subcomposition on every scroll. The new hasInvalidations() method was added for Composition class. hasPendingChanges() method from Recomposer was renamed to hasInvalidations()
Test: This is not changing the behavior so I can't cover it with a unit test, but it dramatically improves the benchmark. So if this optimization will stop working in the future we will get a regression.
Change-Id: Ib2f324dd6845fd83321e0d4f3fa6e502c346dbc3
M compose/runtime/runtime/api/current.txt
M compose/runtime/runtime/api/public_plus_experimental_current.txt
M compose/runtime/runtime/api/restricted_current.txt
M compose/runtime/runtime/src/androidAndroidTest/kotlin/androidx/compose/runtime/AmbientTests.kt
M compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
M compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
M compose/test-utils/src/androidMain/kotlin/androidx/compose/testutils/AndroidComposeTestCaseRunner.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/Wrapper.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
M ui/ui-test/src/androidMain/kotlin/androidx/ui/test/android/ComposeIdlingResource.kt
M ui/ui-test/src/androidMain/kotlin/androidx/ui/test/android/CompositionAwaiter.kt
M ui/ui-test/src/desktopMain/kotlin/androidx/ui/test/DesktopComposeTestRule.kt
https://android-review.googlesource.com/1439054
Branch: androidx-master-dev
commit dc602125a9e5fc15a37ba4fa7610998a94ead29f
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Fri Sep 25 21:14:09 2020
Do less work in SubcomposeLayout when subcompose called with the same lambda
If the lambda object for the slot didn't change and there were no pending recompositons we can skip the whole subcompositions invocation as it will result in unchanged tree. Starting subcomposition is a heavy weight operation so this change allows to improve the measure benchmarks for LazyColumn scrolling by 88 percents.
To achieve it I added a hasPendingChanges() method for Composition class.
Bug: 168293643
Bug: 167972292
Bug: 165028371
Relnote: The scrolling performance of LazyColumn/Row is improved by doing less work in subcomposition on every scroll. The new hasInvalidations() method was added for Composition class. hasPendingChanges() method from Recomposer was renamed to hasInvalidations()
Test: This is not changing the behavior so I can't cover it with a unit test, but it dramatically improves the benchmark. So if this optimization will stop working in the future we will get a regression.
Change-Id: Ib2f324dd6845fd83321e0d4f3fa6e502c346dbc3
M compose/runtime/runtime/api/current.txt
M compose/runtime/runtime/api/public_plus_experimental_current.txt
M compose/runtime/runtime/api/restricted_current.txt
M compose/runtime/runtime/src/androidAndroidTest/kotlin/androidx/compose/runtime/AmbientTests.kt
M compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
M compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
M compose/test-utils/src/androidMain/kotlin/androidx/compose/testutils/AndroidComposeTestCaseRunner.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/Wrapper.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
M ui/ui-test/src/androidMain/kotlin/androidx/ui/test/android/ComposeIdlingResource.kt
M ui/ui-test/src/androidMain/kotlin/androidx/ui/test/android/CompositionAwaiter.kt
M ui/ui-test/src/desktopMain/kotlin/androidx/ui/test/DesktopComposeTestRule.kt
an...@google.com <an...@google.com> #7
There is one optimization for LazyColumn scrolling has been merged in alpha04 and another is upcoming in alpha05.
I will close the bug as fixed for now, Please feel free to comment again if after migrating to alpha05 and starting using loadImageResource for an item the scrolling performance is still unacceptable. Thanks!
I will close the bug as fixed for now, Please feel free to comment again if after migrating to alpha05 and starting using loadImageResource for an item the scrolling performance is still unacceptable. Thanks!
al...@mercari.com <al...@mercari.com> #8
Thanks for your efforts improving the performance of the lazy lists! I was able to observe some improvements.
However it's still slow from my testing on alpha05. I tried removing the image loading (which I was loading with Glide) and just replaced them with Box(Modifier.background(DsToken.colors.backgroundSecondary)
and the )(slow) performance is around the same for the initial scroll.
It seems, when all items have been rendered, it starts to scroll smoothly. So I supposed there's something slow with the initial composition for each of the lazy item. Before, the scrolling was just slow throughout the whole app session.
an...@google.com <an...@google.com> #9
yes, the composition itself is still quite slow. so we do pretty much a lot of work every time we need to compose a new item.
maybe if you can create a working repro sample app which I can check out and debug more?
maybe if you can create a working repro sample app which I can check out and debug more?
Description
Version of Gradle Plugin: gradle:4.2.0-alpha09
OS: Android 9
Compose version : 1.0.0-alpha02
Kotlin compiler: 1.4.0
Problem
When I use LazyColumnFor and try to drag all the list to the end or do a fast drag between items it seems like its choppy and not smooth, if I drag till the end it will glitch on the last item
Example
@Composable
fun RecipeColumnListDemo(recipeList:List<Recipe>){
LazyColumnFor(items = recipeList) { item ->
RecipeCard(recipe = item)
}
}
where RecipeCard(recipe) loads images sincronously
@Composable
private fun RecipeCard(recipe: Recipe){
val image = imageResource(R.drawable.header)
Surface(shape = RoundedCornerShape(8.dp),elevation = 8.dp,modifier = Modifier.padding(8.dp)) {
Column(modifier = Modifier.padding(16.dp)) {
val imageModifier = Modifier.preferredHeight(150.dp).fillMaxWidth().clip(shape = RoundedCornerShape(8.dp))
Image(asset = image,modifier = imageModifier,contentScale = ContentScale.Crop)
Spacer(modifier = Modifier.preferredHeight(16.dp))
Text(text = recipe.title,style = typography.h6)
for(ingredient in recipe.ingredients){
Text(text = "* $ingredient",style = typography.body2)
}
}
}
}
I have also changed the way I load images with loadImageResource, but its also not a smooth scroll when I fast drag to the end of the list
Is this issue on my side ?
I have tried JetChat and it uses a ScrollableColumn which the scrolling is smoother than the the LazyColumnFor
Video: