compose-multiplatform
compose-multiplatform copied to clipboard
Performance issues(missing frames) on LazyColum
Describe the problem
Bad performance on LazyColum( There is no problem with using Colum ) and the content of the screen does not move with the hand (latency)
- Have you noticed any patterns or specific circumstances under which the problem occurs? In both implementations, I used the Instruments tool Allocation and Animation Hitches and Time Profiler. I also tried grab the metal profile. It's all subtle levels. It doesn't seem to be a gpu performance problem. I feel like it's still a cpu problem. The data performance of the two methods is basically the same, but the actual touch is obviously felt with LazyColum jank.
Affected platforms Select one of the platforms below:
- iOS
Versions
- Kotlin version: 1.9.20
- Compose Multiplatform version: 1.6.0
- OS version(s) (required for Desktop and iOS issues): iOS 17.3.1
- OS architecture (x86 or arm64): arm64
- Device: iPhone 13
Sample code
// kotlin
fun getDemoViewController(isIdle: (Boolean) -> Unit): UIViewController {
return ComposeUIViewController(
content = {
LazyColumn(userScrollEnabled = true, modifier = Modifier.fillMaxSize()) {
items((0..100).toList(), { it }) { index ->
Text("Item $index", style = TextStyle(fontSize = 30.sp), modifier = Modifier.height(150.dp))
}
}
// no problem using Column
// Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
// (0..100).forEach { index ->
// Text(
// "Item $index",
// style = TextStyle(fontSize = 30.sp),
// modifier = Modifier.height(150.dp)
// )
// }
// }
}
)
}
//swift
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = UINavigationController(rootViewController: Compose_view_iosKt.getDemoViewController { _ in})
window?.backgroundColor = .white
return true
}
}
Video https://drive.google.com/file/d/1pekBo5D5OI-rkMHCb7byMYbAnsdXcz_c/view?usp=share_link
Profiling data https://drive.google.com/drive/folders/1yndeXWYojDAoYxiZoraq-HVajq0HbbcX?usp=share_link
Bad performance on LazyColum( There is no problem with using Colum)
@elijah-semyonov, could you check it on your device, when you have time? If we have a visible input lag with LazyColumn
comparing to Column
, it is worth to investigate/fix soon. I suspect a few things.
Facing the same issue. The CPU consumption goes ~80% just with LazyColumn.
I'll have a look
Not related to performance, seems like a state update error, investigating further.
https://github.com/JetBrains/compose-multiplatform/assets/4167681/dfd5056a-1fd9-4432-ae3c-4e8bf902aadd
Facing the same issue. The CPU consumption goes ~80% just with LazyColumn.
Not related to this issue, sorry! But the scroll lag is visible.
Facing the same issue...
Facing the same issue, and when start screen recording the scroll behavior so smooth
@m-sasha before your PR will be reviewed and merged, how can I patch the dependency for my project ?
That would be difficult. Just wait for the first dev build after my PR is merged.
@m-sasha thanks for your response
Runs perfectly with the test at JetBrains/compose-multiplatform-core/pull/1260 but unfortunately the "visible jump" comes back when commenting out the LaunchedEffect(Unit) { ... }
, it seems the while-loop in LaunchedEffect(Unit) { ... }
results in something similar to screen recording on iOS, @m-sasha please have a furthur look.
@tipsypotato Not sure I understand. In my reproducer, the LaunchedEffect(Unit){...}
is what is driving the scrolling. Without that it would not scroll.
Can you post a reproducer where the jump is still visible? Is it only visible on iOS? Can you post a video?
@m-sasha Thanks for reply
the
LaunchedEffect(Unit){...}
is what is driving the scrolling.
Yeah but we can also scroll it mannually. I did some further tests, the scrolling experience with LazyColumn is still far from Column when scrolling on a real iOS device, it happened both on iPhoneSE3 and iPhone13 while run perfectly on Android. You can check the iOS screen recording below:
https://github.com/JetBrains/compose-multiplatform/assets/40794760/9129160b-c190-4231-ba92-56b180a4c21e
reproducer code:
@Composable
fun TestLazyColumn() {
Box(modifier = Modifier.fillMaxSize()) {
Row {
Column(
modifier = Modifier
.fillMaxHeight()
.weight(1f)
.verticalScroll(rememberScrollState())
) {
(0..100).forEach { index ->
Text(
"Column item $index",
style = TextStyle(fontSize = 30.sp),
modifier = Modifier.height(150.dp).fillMaxWidth().border(
width = 1.dp,
color = Color.Black
)
)
}
}
LazyColumn(
state = rememberLazyListState(),
modifier = Modifier.fillMaxHeight().weight(1f)
) {
items(100) { index ->
Text(
"LazyColumn item $index",
style = TextStyle(fontSize = 30.sp),
modifier = Modifier.height(150.dp).fillMaxWidth().border(
width = 1.dp,
color = Color.Black
)
)
}
}
}
}
}
@elijah-semyonov I guess more investigation is needed.
@m-sasha I'll have another look.
I struggle to reproduce it on 11 Pro Max and 14 Pro after the fix. Can you use slomo camera from the other device to verify (to avoid observer effects such as ones that could be caused by screen recording)?
https://github.com/JetBrains/compose-multiplatform/assets/4167681/91867b71-5679-41e3-8c73-36bd5b1f2a0c
https://github.com/JetBrains/compose-multiplatform/assets/4167681/6b6ad933-68b7-494d-9dd0-9cfcae7fe83d
I'm experiencing the same issue, along with an additional one. It will become apparent when you scroll up. https://github.com/JetBrains/compose-multiplatform/assets/36324542/79224172-abda-4e08-b95d-8ce4f75a6487
@jnelle Can you describe what you think you see? I'm not sure what to focus on exactly.
I think he means the list seems to scroll to a random far position sometimes. But this is a different issue, possibly a bug in the user code. Please post a reproducer in a new issue.
@elijah-semyonov In your second slomo video 14_pro.mov
, the stutter happens at 0:09, 0:13, 0:23 and 0:26, and after several attempts with my reproducer, I noticed the stutter unexpectedly happens on Column when scrolling both at the sametime, while when scrolling the Column or the LazyColumn only, it seems the stutter only happens with LazyColumn.
@tipsypotato Yeah, it's a debug build. Release build is much better (though can also have occasional stutters due to GC). Can you check if you have this behavior on release builds?
@elijah-semyonov I'm facing the performance issues when I scroll down and also when I scroll up the list skips random positions.
Here is the reproducible code:
is UiState.Success -> {
LazyColumn(modifier = Modifier.padding(innerPadding)) {
items(count = (uiState as UiState.Success<MainFeedResponse>).data.clips.size) {
Card(
Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp),
) {
Image(
painter = rememberImagePainter(
(uiState as UiState.Success<MainFeedResponse>).data.clips[it].image
),
contentDescription = "image",
)
Text((uiState as UiState.Success<MainFeedResponse>).data.clips[it].title)
}
}
}
}
You'll find the repository here:
https://github.com/Nelle-Bendlage-IT/MassengeschmackTV
@jnelle Thanks, I'll have a look!
@elijah-semyonov I'm also facing the performance (stutters) issues on my Pixel 6 Pro, but it could be possible that this is caused from debug build. But the scroll behavior is also wrong but not the same as one iOS.
https://github.com/JetBrains/compose-multiplatform/assets/36324542/8501b99b-f5d9-4f8d-9b63-7a70fc5ae71f
@jnelle We don't have an ownership over Android implementation. Could you please file an issue to Google Compose Issue tracker and paste a link here?
@tipsypotato Yeah, it's a debug build. Release build is much better (though can also have occasional stutters due to GC). Can you check if you have this behavior on release builds?
@elijah-semyonov It still happens with release build on iOS, the stutters are frequent and subtle, but still very noticeable compared to Column. Our project uses lots of LazyColumn, so it would be very appreciated if you could give it a further look!
@tipsypotato Apart from the issues you've noticed on my slowmo video, do you see something else? I'm trying to figure out if it's yet another lazy-column bug that we are not aware of (like the initially reported one), or general performance issues, which we are already working on.
@elijah-semyonov add the code below to TestLazyColumn
in the reproduce code above, the lazy-column performance issue will be gone.
LaunchedEffect(Unit) {
while (true) {
withFrameMillis {}
}
}
@tipsypotato this code snippet makes me think that it's probably related to https://github.com/JetBrains/compose-multiplatform-core/pull/1356
@MatkovIvan As https://github.com/JetBrains/compose-multiplatform-core/pull/1356 is merged, any chance to have a try with a dev-release?