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

使用Jetpack Paging3时列表首次滚动卡顿问题求助

Paging3集成首次滚动卡顿问题排查

问题背景

我创建了一个集成Jetpack Paging3分页库的简单示例项目,项目地址:Paging3-Sample
目前页面触发第一次滚动时会出现明显卡顿,始终无法定位问题原因,各层实现代码如下:

PagingSource层实现

private const val STARTING_PAGE_INDEX = 1

class ShowPagingSource(
    private val service: ShowService
) : PagingSource<Int, Show>() {

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Show> {
        val page = params.key ?: STARTING_PAGE_INDEX
        return try {
            val response = service.fetchShowList(page)
            LoadResult.Page(
                data = response,
                prevKey = if (page == STARTING_PAGE_INDEX) null else page - 1,
                nextKey = if (response.isEmpty()) null else page + 1
            )
        } catch (exception: IOException) {
            LoadResult.Error(exception)
        } catch (exception: HttpException) {
            LoadResult.Error(exception)
        }
    }
}

Repository层实现

@Singleton
class ShowRepositoryImpl @Inject constructor(private val service: ShowService) : ShowRepository {

    override val fetchResultStream: Flow<PagingData<Show>> = Pager(
        config = PagingConfig(pageSize = NETWORK_PAGE_SIZE),
        pagingSourceFactory = { ShowPagingSource(service) }
    ).flow


    companion object {
        const val NETWORK_PAGE_SIZE = 245
    }
}

ViewModel层实现

@HiltViewModel
class ShowViewModel @Inject constructor(
    repository: ShowRepository
) : ViewModel() {

    val pagingDataFlow: Flow<PagingData<Show>> =
        repository.fetchResultStream.cachedIn(viewModelScope)
}

Activity层数据提交逻辑

lifecycleScope.launch {
    viewModel.pagingDataFlow.collectLatest(showAdapter::submitData)
}

核心疑问:现有实现是否存在遗漏配置?首次滚动卡顿的根本原因是什么?


问题根因与修复方案

首次滚动卡顿完全是配置不合理导致的,不存在遗漏的核心逻辑,具体问题点和修复方式如下:

  • pageSize配置严重偏大:当前设置单页加载245条数据,远高于移动端列表单页加载的合理区间(常规取值20-50条)。Paging3默认的预加载触发距离与pageSize相等,且首次加载大小默认是pageSize的3倍,该配置下首次会拉取700+条数据,DiffUtil在主线程对比数百条数据差异时会直接阻塞UI线程,引发明显卡顿。
  • 占位符配置与Adapter实现不匹配:PagingConfig默认开启占位符(enablePlaceholders = true),如果Adapter没有实现对应占位符ViewHolder逻辑,Paging3计算列表总高度、滚动偏移时会出现偏差,首次滚动时会瞬间插入大量条目触发全列表重绘,进一步加剧卡顿。不需要占位符时直接显式关闭该配置即可。
  • 缺少RecyclerView基础优化:检查RecyclerView是否调用了setHasFixedSize(true),列表项布局是否使用固定高度避免滚动时重复触发measure/layout;同时确认Show数据类正确实现了equals和hashCode方法,否则DiffUtil会做全量数据对比,额外增加大量主线程耗时。

修复参考配置

修改Repository层的Pager配置即可解决绝大多数卡顿场景:

Pager(
    config = PagingConfig(
        pageSize = 30, // 单页加载条数调整到合理区间
        prefetchDistance = 10, // 距离底部10条时提前触发预加载
        enablePlaceholders = false, // 未适配占位符则显式关闭
        initialLoadSize = 30 // 首次加载大小与pageSize对齐,避免首次拉取数据过多
    ),
    pagingSourceFactory = { ShowPagingSource(service) }
).flow

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:21:49