You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose LazyRow性能远逊于XML RecyclerView?求优化方案

问题:低配置设备上Jetpack Compose LazyRow卡顿,XML RecyclerView却流畅

我正在给配置极低的硬件开发应用,选用了Jetpack Compose。展示卡片列表时,LazyRow滚动严重卡顿,但用XML的RecyclerView展示几乎一致的卡片列表,滚动却极为流畅。是Jetpack Compose本质比XML视图慢,还是我用法有误?

已尝试的优化

  • 运行Release模式
  • 在build.gradle中设置minifyEnabled和shrinkResources为true
  • 在gradle.properties中设置android.enableR8.fullMode为true
  • 给LazyRow的items设置key

这些操作有一定效果,但流畅度仍远不如RecyclerView的XML实现。

核心代码

主Composable与LazyRow

@Composable
fun mainComposable(){
    ...
    cardList = remember{ arrayListOf(...) }
    lazyList(cardList)
    ...
}

@Composable
fun lazyList(
cardList: List<CardContent>,
){
    LazyRow(
        horizontalArrangement = Arrangement.spacedBy(16.dp),
        contentPadding = PaddingValues(horizontal = 32.dp)

        ) {
        items(
            items = cardList,
            key = { it.id }) { item ->
            CardComposable(
                content = item
            )
        }
    }
}

补充的CardComposable代码

@Composable
fun CardComposable(
    content: Content,
) {

    Card(
        shape = RoundedCornerShape(8.dp),
        elevation = 1.dp,
        modifier = Modifier
            .width(216.dp)
            .height(308.dp)
    ) {
        Column {

            Box(contentAlignment = Alignment.TopEnd) {
                Image(
                    painter = painterResource(id = content.image),
                    modifier = Modifier
                        .width(216.dp)
                        .height(164.dp)
                )
                Box(
                    contentAlignment = Alignment.Center,
                    modifier = Modifier.padding(8.dp)
                ) {
                    Image(
                        painter = painterResource(id = R.drawable.button_background),
                        modifier = Modifier
                            .width(40.dp)
                            .height(40.dp)
                    )
                    Icon(
                        painter = painterResource(id = R.drawable.button),
                        modifier = Modifier
                            .width(16.dp)
                            .height(16.dp),
                        tint = GenericRedColor
                    )
                }
            }

            Column(
                modifier = Modifier
                    .padding(start = 16.dp)
            ) {

                Row(verticalAlignment = Alignment.CenterVertically) {
                    Text(
                        text = content.Name,
                        maxLines = 2,
                        color = GenericBlackColor,
                        fontSize = 16.sp,
                        fontWeight = FontWeight(500),
                        overflow = TextOverflow.Ellipsis,
                        modifier = Modifier
                            .width(134.dp)
                            .padding(top = 16.dp)
                    )

                    Box(
                        contentAlignment = Alignment.Center,
                        modifier = Modifier.padding(start = 16.dp, top = 8.dp)
                    ) {
                        Icon(
                            painter = painterResource(id = R.drawable.square_button),
                            modifier = Modifier
                                .width(32.dp)
                                .height(32.dp),
                            tint = GenericRedColor
                        )
                        Icon(
                            painter = painterResource(id = R.drawable.button_icon),
                            modifier = Modifier
                                .width(16.dp)
                                .height(16.dp),
                            tint = GenericWhiteColor
                        )
                    }
                }

                Text(
                    text = content.contentType,
                    color = GenericLightGrayColor2,
                    fontSize = 14.sp,
                    modifier = Modifier.padding(top = 8.dp)
                )

                Row(
                    horizontalArrangement = Arrangement.spacedBy(26.dp),
                    modifier = Modifier.padding(top = 24.dp)
                ) {

                    val iconModifier = Modifier
                        .padding(end = 4.dp)
                        .width(12.dp)
                        .height(12.dp)

                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Icon(
                            painter = painterResource(R.drawable.icon_1),
                            modifier = iconModifier,
                            tint = GenericLightGrayColor2
                        )
                        Text(
                            text = content.text_1,
                            fontSize = 14.sp,
                            color = GenericLightGrayColor2
                        )
           
                        Icon(
                            painter = painterResource(R.drawable.icon_2),
                            modifier = iconModifier,
                            tint = GenericLightGrayColor2
                        )
                        Text(
                            text = content.text2,
                            fontSize = 14.sp,
                            color = GenericLightGrayColor2
                        )
       
                        Icon(
                            painter = painterResource(R.drawable.icon_3),
                            modifier = iconModifier,
                            tint = GenericLightGrayColor2
                        )
                        Text(
                            text = content.text3,
                            fontSize = 14.sp,
                            color = GenericLightGrayColor2
                        )
                    }
                }
            }
        }
    }
}

解决方案

Compose本身并不比XML慢,低配置设备上的卡顿大多是因为Composable的绘制/重组优化不到位。针对你的代码,可做以下优化:

1. 优化图片加载

  • 替换painterResource为Coil或Glide的Compose扩展库,这类库支持图片缓存、内存管理、渐进式加载,能大幅降低滚动时的内存压力,避免频繁GC。
  • 确保所有图片资源适配设备分辨率,避免加载过大尺寸的图片后再压缩显示,减少不必要的计算开销。

2. 减少Composable重组范围

  • 给自定义数据类Content添加@Stable注解(数据类默认会被Compose识别为稳定类型),让Compose能感知数据变化,避免不必要的重组。
  • 将CardComposable中的固定修饰符、颜色值提取为全局常量,比如GenericRedColor、iconModifier,避免每次重组创建新对象。

3. 简化布局层级

  • 移除不必要的嵌套布局:比如最外层的Column可以和Card的内容直接合并,减少布局层级,降低测量和绘制的计算量。
  • 对于固定尺寸的元素,提前指定明确的宽高,避免Compose重复计算布局约束。

4. 关闭高开销绘制特性

  • 暂时关闭Card的阴影效果:将elevation设为0.dp,阴影绘制对GPU开销较大,批量卡片滚动时尤为明显。如果需要阴影,改用带阴影的静态图片替代动态生成的阴影。
  • 移除Text的自定义fontWeight,改用系统默认权重,减少文本测量的计算量。

5. 强化编译与运行时优化

  • 确认开启Compose编译优化:在gradle.properties中添加android.enableComposeCompiler=true(高版本默认已开启),让编译器自动优化重组逻辑。
  • 确保Release模式下完全禁用调试特性,比如移除LocalInspectionMode相关代码,避免额外性能损耗。

通过以上优化,LazyRow的流畅度应该能接近甚至达到RecyclerView的水平。低配置设备上的Compose性能优化核心是减少重组、降低内存占用、简化绘制逻辑。


内容的提问来源于stack exchange,提问作者Pedro Oliveira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:31:11