Flutter中ListView与Column性能优化:官方文档相关说明如何理解?
官方建议含义解释
官方这句话的核心逻辑非常简单:当你要展示的子组件数量超过一屏可视范围时,不要用「一次性生成全部子组件传给容器」的写法,否则那些用户当前看不到的组件也会消耗资源完成构建、布局流程,产生不必要的性能开销。
为什么这类写法会有额外开销
Column、Row这类非懒加载容器本身没有滚动能力,很多开发者会在外层套SingleChildScrollView实现滚动,但这种组合会一次性构建所有传入的子组件,哪怕子组件远在屏幕之外,也会走完完整的Flutter渲染流水线,子组件数量越多,性能损耗越明显。- 即便是滚动容器
ListView,如果用默认的ListView(children: [])构造方法传入全量子组件,和套了SingleChildScrollView的Column没有本质区别,同样会一次性构建所有子组件,不会做懒加载处理。
反面示例(不推荐的写法)
示例1:SingleChildScrollView + Column 实现长列表
// 不推荐:100个条目会在页面初始化时全部完成构建,首屏仅能展示约10个,剩下90个的构建属于完全不必要的开销 SingleChildScrollView( child: Column( children: List.generate(100, (index) => ListTile(title: Text('列表条目$index'))), ), )
示例2:默认构造函数的ListView实现长列表
// 不推荐:和上面的写法性能表现完全一致,同样会一次性构建全部100个条目 ListView( children: List.generate(100, (index) => ListTile(title: Text('列表条目$index'))), )
正确优化方案
对于子组件数量多、无法一屏展示的场景,统一使用Flutter提供的懒加载构造方法,这类方法只会构建当前视口内可见的子组件,滑到对应位置才会生成新的子组件,性能提升非常明显:
// 推荐:仅构建当前屏幕可见的条目,不可见的部分不会提前构建 ListView.builder( itemCount: 100, itemBuilder: (context, index) => ListTile(title: Text('列表条目$index')), )
如果是网格布局可以用GridView.builder,需要自带分割线的列表可以用ListView.separated,都是懒加载的实现。
补充说明
如果你的子组件数量很少(比如3-5个),一屏就能完全展示,那用Column或者默认的ListView完全没问题,不需要刻意使用懒加载构造,只有当子组件数量多、会超出一屏范围时才需要做这个优化。
内容的提问来源于stack exchange,提问作者Ardeshir ojan
相关产品推荐
相关产品推荐

