Laggy Lazy Column Android Compose

Mat*_*tti 57 android kotlin kotlin-coroutines android-jetpack-compose coil

我在Jetpack Compose中创建了一个完整的应用程序。然而,其表现Lazy Column非常糟糕,而且没有任何意义。Lazy Column应该是 的替代品RecyclerView,但RecyclerView目前效果更好。

我制作了一个Lazy Column带有标题和Lazy Rows项目的项目(基本上是一个嵌套列表)。正如您所看到的,有图像,但我使用了Coil 库,因此所有内容都应该在单独的线程中加载。我已经看过这些讨论:link1link2。但似乎这个问题还没有解决方案,尽管现在Jetpack Compose已经稳定了。

你们中有人找到了获得更好性能的方法吗?还是我应该用 来Lazy Rows代替RecyclerView

这是页面的屏幕:

在此输入图像描述

Mat*_*tti 89

Things will speed up your Lazy List

  1. If you're in debug mode, that's normal. Don't worry if your app is laggy in debugging. It's completely fine. Just create the APK in release mode (Build -> Generated Signed Bundle/APK), which might solve your problem. This happens because when in debugging, Compose translates bytecode in runtime using JIT. Make sure you're also using the R8 compiler in the release build. This is extremely important to improve general performance.

  2. Set a key for your item. Initialize your Lazy list like this.

LazyColumn() {
    items(
        count = cartItems.size,
        key = {
            cartItems[it].cartItem.id
        },
        itemContent = { index ->
            val cartItemData = cartItems[index]
            CartItemWithActions(data = cartItemData)
            Divider(
                color = colorResource(id =R.color.separator_line)
            )
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

Setting a key works similar to the DiffUtil class in RecyclerView. Check the Maciej Przybylski's post.

  1. Make sure every variable is using the remember{} block.
@Composable
fun MyComposable() {
    ...
    val wrongList = myViewModel.getList() // <- Don't do this
    val correctList = remember { myViewModel.getList() } // <- Do this
    ...
}
Run Code Online (Sandbox Code Playgroud)
  1. You can also use contentType, which defines the type of object in a list. This is useful if you have headers or different types of objects in your list. Learn more here.

  2. Baseline Profiles. If you've tried everything but your list is still missing frames this might be it. In this talk, Rahul Ravikumar (Google engineer) reveals how Baseline Profiles improve performances up to 40%. What's this? Compose is a library and not native XML. This means that every time you execute your app, the code has to be translated at runtime. You can pre-execute and save all this code when installing the app using Baseline Profiles. Check these links: Baseline Profiles, Improving Performance with Baseline Profiles.

Check these resources never to have performance issues again. I highly suggest watching these videos: Optimizing Render Performance of Jetpack Compose, Performance best practices for Jetpack Compose, and reading this post.

A Good News

Generally speaking, Jetpack Compose is not great in terms of performance compared to XML. We now know this issue is due to the way Modifiers have been created. I highly suggest you watch this video. The good news is that the Jetpack Compose team has been working on a new way to improve performance for a few months now. This new way leverages the use of Modifier.Node to avoid executing lots of useless operations under the hood. The best thing about this approach is that you won't be required to change anything in your code, and it will be completely retro-compatible.

Available from Jetpack Compose 1.5.0

Original Answer

SOLVED! Reading this reddit I found out the problem is only in the debug version. It seems crazy but it's true. That's because debug versions of Compose apps have a lot going on under the hood which impacts performance (pretty similar to what happens with Flutter). To solve the problem the only thing you need to do is to create a release version of your app. To do that, go to Build -> Generated Signed Bundle/APK. Create the key and then select release.

Enjoy your smooth app!

  • 另请考虑观看 https://www.youtube.com/watch?v=Ry-3xlElUe4,其中包含大量有关如何优化撰写应用程序的重要信息(包括您从 reddit 发现的信息)。 (3认同)
  • 我不需要构建 apk 就能看到更好的性能。在我的例子中,只需将构建变体作为发布版本即可解决性能问题。 (2认同)