如何优化 JetPack Compose 列表性能?

How optimize JetPack Compose list performance?

我有一个简单的可组合函数,其中包含 LazyColumn:

@Composable
fun MyScreen(itemList: List<Item>) {
    LazyColumn {
        intems(itemList) {
            ...
        }
    }
}

一切正常,但当滚动到达某个位置索引时,我的 ViewState(itemList) 应该会改变。这就是为什么我将以下行添加到我的可组合函数中:

@Composable
fun MyScreen(itemList: List<Item>) {
    val lazyListState = rememberLazyListState()
    viewModel.onPositionChanged(lazyListState.firstVisibleItemIndex)
    LazyColumn(state = lazyListState) {
        intems(itemList) {
            ...
        }
    }
}

一切如我所料,但性能明显下降。我该如何解决?

你这里有两个问题:

  1. 您正在使用 lazyListState.firstVisibleItemIndex 直接读取可组合项中的状态,这会导致继续重组 - 每次 lazyListState 的任何部分发生变化时,例如在每个滚动像素上。
  2. 您正在直接从可组合项进行 viewModel.onPositionChanged 调用。建议从特殊的副作用函数进行此类调用,阅读 thinking in compose and side effects documentation.
  3. 中有关该主题的更多信息

在这种情况下 LaunchedEffectsnapshotFlow 可以像这样使用:

LaunchedEffect(Unit) {
    snapshotFlow { lazyListState.firstVisibleItemIndex }
        .collect(viewModel::onPositionChanged)
}

当您需要根据列表状态更新视图时,您也可能遇到同样的问题。在这种情况下应该使用derivedStateOf:只有当计算值实际改变时才会导致重组。

val firstVisibleItemIndex by remember {
    derivedStateOf {
        lazyListState.firstVisibleItemIndex
    }
}