Android ViewPager2 是否提前预创建Fragment的性能差异对比
ViewPager2 两种 Fragment 提供方式的性能差异
以下是两种实现的具体差异:
- 初始化性能
方式2会在Adapter实例化时一次性创建全部Fragment实例,所有Fragment的初始化成本(包括onCreate生命周期执行、布局初始化、初始数据加载等)都会集中在Adapter创建阶段,如果Fragment逻辑较重,会直接拖慢当前页面的首次渲染速度。
方式1仅在用户滑动到对应位置时才创建目标Fragment,初始化成本分散到滑动操作时触发,当前页面首次加载速度更快。 - 内存占用
方式2无论用户是否访问对应页面,所有Fragment实例都会常驻内存,如果Fragment持有大量数据(比如Bitmap、长列表数据集),会造成不必要的内存占用,页面数量越多内存浪费越严重。
方式1遵循FragmentStateAdapter的默认缓存逻辑,默认仅保留当前可见Fragment+左右各1个离屏Fragment实例,其余未访问/超出缓存范围的Fragment会被销毁回收,内存占用更低,更适合页面数量多、单Fragment内存开销大的场景。如果用户频繁来回滑动超出缓存范围的页面,方式1会产生少量的实例创建销毁开销,这种场景下方式2的内存占用更高但没有反复创建的开销。 - 滑动流畅度
若单Fragment初始化逻辑极轻,两种方式滑动流畅度无感知差异。
若单Fragment初始化逻辑较重,方式1在首次滑动到未访问过的页面时会出现短暂卡顿,后续滑动时因为实例已被缓存则无卡顿;方式2因为所有实例提前创建完成,滑动全程无卡顿,但卡顿成本前置到了页面首次加载阶段。 - 功能隐患(非性能但影响可用性)
方式2存在稳定隐患:FragmentStateAdapter本身会在配置变更(比如屏幕旋转、系统语言切换)时自动恢复之前的Fragment实例,此时你预存的Fragment实例和系统恢复的实例并不一致,会出现Fragment重叠、状态丢失、点击事件失效等异常问题。而方式1完全遵循系统的实例管理逻辑,不存在这类问题。
最佳实践建议:如果确实需要全量缓存
Fragment提升滑动流畅度,不需要自己预存实例,直接调用viewPager2.offscreenPageLimit = 页面总数即可,既可以实现全量缓存,又能兼容系统的Fragment状态管理逻辑,避免自定义缓存带来的bug。
内容的提问来源于stack exchange,提问作者Sam Chen
相关产品推荐
相关产品推荐

