Flutter 是一款跨平台的 UI 框架,能够快速构建出高品质、高性能的应用程序。当应用程序中需要大量展示条目时,通常会用到滚动列表(也称为滑动容器、ListView)来优化性能。但是,如果不进行优化,大量的数据渲染将会占用大量的内存,导致应用程序的性能下降甚至崩溃。因此,本文将围绕 Flutter 高性能滚动列表的优化实践展开,通过深入分析实现方案、性能优化技巧,展现在开发时如何减小渲染成本,提高用户体验。
ListView
在 Flutter 中,滚动列表通常用 ListView 来实现。在 ListView 中,Flutter 可以很容易地实现两种类型的列表:
普通列表
普通列表显示的是一些水平或垂直的文本或者图片等等。大部分 Flutter 应用程序里常常需要用这种类型的滚动列表。我们可以通过以下代码来实现:
-- -------------------- ---- ------- --------- --------- --------- --------- -------- ------------------ ------ -------------- --------- ---------- ----- -- --------- -------- ------------------ ------ -------------- --------- ---------- ----- -- --------- -------- ------------------ ------ -------------- --------- ---------- ----- -- -- --
GridView
GridView 是另外一种常用的滑动列表,它可以显示一些布置在二维网格中的列表。GridView 有许多不同的展示方式,如以下两个例子:
-- -------------------- ---- ------- --------------- --------------- -- --------- --------- ---------- ------- --- ------ ----------------------------------- -- ---------- ------- --- ------ ----------------------------------- -- ----- -- --
-- -------------------- ---- ------- ----------------- ------------- ------------------------------------------ --------------- -- ---------------- ---- ----------------- ---- -- ------------ ------------- -------- --- ------ - ------ ---------- ------- --- ------ ---------------------------------- - --------- -- -- ---------- -- --
列表的性能问题
如果列表中的数据量较小,那么不用过多考虑性能问题。但是如果列表中的数据量很大,那么这时候就需要考虑性能问题了。这篇文章主要介绍以下针对滚动列表性能的优化措施:
- 池化(缓存)机制
- 视域(ViewPort)机制
- 数据预拉取(Pre-Fetching)机制
池化(缓存)机制
池化机制就是为了复用滑动列表子项的内存,降低Flutter的内存占用,减少Flutter的垃圾回收,提高滑动效率。Flutter通过子项复用的方式来实现缓存数据、控件的优化。针对可变长度的列表Flutter通过“滚动池”(ScrollPools)的方式来缓存列表子项。这样的设计能够减少Flutter对于子项内存的申请和释放,可以降低程序卡顿的概率,提高Flutter应用的性能。我们可以通过以下代码来实现:
ListView.builder( itemCount: 1000, itemBuilder: (BuildContext context, int index) { return Text('Index: $index'); }, );
ListView.builder 告诉 Flutter 想要显示 1000 项,并设置显示每项是 Text('Index: $index') 。这时候 Flutter 会根据当前的滑动位置动态地缓存一小部分选项,而不是渲染所有的 1000 项。当向上或向下滑动时,Flutter 会自动将已经渲染完成的选项从缓存池中取出来重用,然后使用新的数据更新它们。 如此一来,ListView.builder 就能够具备更高的性能和更低的内存消耗。
视域(Viewport)机制
在滚动列表中,视域指的是当前可见的部分。对于想要大量展示列表的应用来说,保证视域内的内容能够进行快速的绘制,非常关键。因此,Flutter 提供了一种名为 SliverList 和 SliverGrid 的机制,可以将列表控件可见的部分作为一个片段来渲染。当向上或向下滚动该列表时,Flutter 会回收那些超出视域范围的区域,这样一来,一只滑动指令就能够高效的完成,保证了应用程序的流畅。
使用 Sliver 来构建滑动列表,是一种高度灵活、可定制且可扩展的方式。Flutter 的滚动列表架构基于可组合的 Sliver 布局。Sliver 是对需要组合在一起的不同部分的列表进行建模的一种方式,每个不同部分都独立的被构建、更新和绘制。Sliver 布局使得列表可以很容易的进行扩展,如添加头部、分割线等等。Sliver 布局也让我们可以覆盖默认的 Flutter 列表样式,并完全控制滚动列表的所有部分。
ListView(以及其他所有滚动列表组件)都是由多个 Sliver 组成的组合。最常用的基础 Sliver 组件有五种:
- SliverAppBar:带着滑动出现和收起效果的应用栏。
- SliverList:在线性方向上排列子项的视图。
- SliverFixedExtentList:每一行子项拥有确定高度的基于 SliverList 的实现。
- SliverGrid:将子项排成二位的视图。
- SliverPadding:在视图周围添加一些装饰。
数据预拉取(Pre-Fetching)机制
预拉取可以增加你的组件的渲染效率。当你的应用程序中滑动容器快要滚到底时,预拉取机制可以先加载部分数据,减少视图的输入延迟。这个机制同样可以帮助用户在快速滚动容器时获得更好的体验,并且减少了 Flutter 应用程序的内存占用和性能消耗。
Flutter 滑动容器的预拉取机制依赖于 ScrollController,一个控制滑动容器滚动位置的对象。当某个/一些/所有子项进入/准备进入可见区域时(ScrollOffset),Flutter 会触发 ScrollController 的回调函数。借此回调函数,我们可以知道容器的滑动位置,以及预拉取进行到哪一行。这样子就可以及时加载需要展示的数据,同时确保用户在下一次滚动时依然可以像往常一样流畅的操作。
可以使用以下代码来实现数据预拉取机制:
-- -------------------- ---- ------- ----- ---------------- ----------- - ------------------- --------- ---- ----------- - ------------------ ----------------------------------- - ---- ----------- - ----- ---------- - ---------------------------- -- -------- ----- ------ - ------------------------------------ - --- -- ----------- -- ------- - -- ------- ----------- - ----------------------------------- -------------- ---- ------------- - ----- --- - - ----- ----------------- ----------- ------------ ---------- -------------- ------------ ------------- -------- --- ------ - ----- -- --
总结
尽管 Flutter 在大量列表项目的渲染上表现非常优异,但是我们仍然需要遵循最佳实践来确保最佳绩效。广泛的消费层应用程序使用普通的 ListView 是没有问题的,但在某些使用情形下,特别是需要大量元素渐进地加载或需要提供视差效果的应用,使用可定制的 Sliver 布局就更加合适。我们在 Flutter 中可以通过下面的方式来优化许多常见的应用程序滚动列表展示。
- 充分利用池化(缓存)机制,尽量避免因创建过多的新对象而导致 Flutter 的内存消耗过大,影响用户体验。
- 遵循视域(Viewport)机制,保证视域内(可见区域内)的内容能够准确高效地渲染,降低因性能问题而导致的页面卡顿。
- 按照实际需求设置合理的数据预拉取(Pre-Fetching)机制,缩短等待时间,快速响应用户的操作。
总的来说,只有遵循最佳实践、紧跟技术潮流、灵活多变,才能在 Flutter 应用的性能优化方面做得更好,满足不同用户的需求,减少因性能问题而导致的流失率,提高用户留存率。本文尝试通过深入分析实现方案和性能优化技巧,帮助读者更好地理解和掌握 Flutter 高性能滚动列表的真谛,为 Flutter 应用的性能优化提供参考和指导。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64c6f65310032fedd3902f9b