Horizo​​ntalPager Jetpack Compose 性能不佳

The*_*awd 9 android android-jetpack android-jetpack-compose jetpack-compose-accompanist baseline-profile

我的应用程序整体性能相当不错,唯一 FPS 下降的部分是在伴奏者滑动 Horizo​​ntalPager 时。

每个页面都有一个简单的 LazyVerticalGrid,有 3 个固定列,但与 XML 相比,性能要差得多。

LazyVerticalGrid 的外观如下:

在此输入图像描述

出于测试目的,我在 XML 中开发了相同的设置,以使用 Perfetto 和 Android Studio 编译器进行比较。与 XML 相比,Jetpack Compose 版本具有更多的 Janky 框架。

这是 Perfetto 中 compose 的结果:

在此输入图像描述

这里是 XML:

在此输入图像描述

此外,每次我滑动 Horizo​​ntalPager 时,Profiler 都会显示一堆卡顿的帧:

在此输入图像描述

我拥有 Jetpack Compose 的基本知识,并且还阅读了 Android 开发人员 Compose 性能指南,我非常确定我没有做任何导致大量重组的愚蠢事情。

这是我在测试项目中使用的代码:

可滚动 TabRow + Horizo​​ntalPager:

val tabList = listOf("Following", "Trending", "New", "Top", "Most Shared", "Most Saved", "All")
val pagerState: PagerState = rememberPagerState(initialPage = 1)
val coroutineScope = rememberCoroutineScope()

Column(
    modifier = Modifier
        .fillMaxSize()
        .background(MaterialTheme.colors.background)
) {
    ScrollableTabRow(
        modifier = Modifier.fillMaxWidth(),
        backgroundColor = MaterialTheme.colors.surface,
        contentColor = Color.White,
        edgePadding = 8.dp, 
        selectedTabIndex = pagerState.currentPage, 
        indicator = { tabPositions ->
            TabRowDefaults.Indicator(
                Modifier.pagerTabIndicatorOffset(pagerState, tabPositions),
                color = MaterialTheme.colors.primary
            )
        }
    ) {
        // Add tabs for all of our pages
        tabList.forEachIndexed { index, title ->
            Tab(
                text = { Text(title) },
                selected = pagerState.currentPage == index,
                onClick = {
                    coroutineScope.launch {
                        pagerState.animateScrollToPage(index)
                    }
                },
            )
        }
    }

    HorizontalPager(
        state = pagerState,
        count = tabList.size
    ) { page: Int ->
        when (page) {
            0 -> MyList()
            1 -> MyList()
            2 -> MyList()
            3 -> MyList()
            4 -> MyList()
            5 -> MyList()
            6 -> MyList()
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的列表:

@Composable
fun MyList(){
    LazyVerticalGrid(
        modifier = Modifier.fillMaxSize(),
        columns = GridCells.Fixed(3),
        content = {
            items(100) { item ->

                Button(onClick = { /*TODO*/ }) {
                    Text(text = "Hello")
                }
            }
        })


}
Run Code Online (Sandbox Code Playgroud)

我在 Samsung Galaxy s10+ 上启用了 R8 并在发布模式下运行。总体而言,上述设置的性能不会造成任何巨大的可见 FPS 下降,但它仍然明显不如 XML 流畅,问题是我需要在 LazyVerticalGrid 项目中添加更多内容,而不仅仅是一个带有“Hello”字样的简单按钮”。对于我的设置,我需要在每个项目中:

  • 1x 512x512 网页图像
  • 2x 文本视图
  • 2x 图标
  • 1x 卡与海拔

我添加的项目越多,滞后就越明显。这些项目大致如下所示:

在此输入图像描述

在我的 Jetpack Compose Horizo​​ntal Pager 中运行此程序会导致严重滞后(大约 10 fps),并导致用户体验非常差。

Jetpack Compose Slack 频道的有人建议定义基线配置文件,据我正确理解,这些只会提高启动性能和第一次使用库时的性能。不幸的是,这不会修复我的 Horizo​​ntalPager 性能。

除了切换回 XML 之外,还有其他方法可以提高 Horizo​​ntalPager 性能吗?

当前使用 Compose 版本 1.3.0-beta01 和 Kotlin 1.7.10。如果有人能告诉我上面的代码是否也会导致他们的设备上出现卡顿帧,我会很高兴。

更新

我为水平寻呼机滑动手势创建了一个基线配置文件,并使用 Macrobenchmark 对其进行了测试。结果看起来很有希望:

在此输入图像描述

但不幸的是,侧载基线配置文件时没有明显的变化,它仍然很卡顿。

这是基线配置文件:

@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {

    @OptIn(ExperimentalBaselineProfilesApi::class)
    @get:Rule
    val rule = BaselineProfileRule()

    @OptIn(ExperimentalBaselineProfilesApi::class)
    @Test
    fun generate() {
        rule.collectBaselineProfile("com.example.composespeedtest") {


            startActivityAndWait()
            device.wait(Until.hasObject(By.res("horizontal_pager")), 10_000)
            val snackList = device.findObject(By.res("horizontal_pager"))
            snackList.setGestureMargin(device.displayWidth / 5)
            snackList.scroll(Direction.RIGHT, 1f)
            device.waitForIdle()
 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)