ListView复用:哥布林也能分分钟实现?实验性想法和发现
2023-09-03 08:16:17
前言
这篇文章是对最近 Flutter 中 ListView 研究的总结。一直以来,我对 Flutter 的设计都不太感兴趣,尤其是在完成那个支持仿真翻页的小说阅读器的时候。我经常想:一个声称以性能为傲的框架,为什么在实现一个如此基本的功能(列表视图)时如此复杂?
问题
在 Flutter 中,ListView 的复用性一直是一个问题。当列表项数量较多时,频繁创建和销毁 widget 会导致性能问题。为了解决这个问题,Flutter 提供了几个内置解决方案,例如 SliverList
和 IndexedListView
。然而,这些解决方案要么功能受限,要么不够灵活。
实验
为了探索 ListView 复用的替代方法,我进行了一些实验。我的目标是创建一个高性能、高度可定制的 ListView,它可以处理大数据集。
第一个实验是使用 CustomScrollView
和 SliverFillViewport
来模拟 ListView 的行为。通过这种方式,我可以手动控制列表项的创建和销毁。这个方法非常有效,但是实现起来很复杂,而且不适用于所有场景。
第二个实验是使用 RenderObject
来直接操作 Flutter 的渲染管道。这个方法给了我完全的控制权,但是它需要对 Flutter 的内部工作原理有深入的了解。而且,它违反了 Flutter 的封装原则,可能会导致意外后果。
发现
通过这些实验,我得出了一些关于 ListView 复用的重要发现:
- 手动管理 widget 生命周期是至关重要的。 通过手动控制 widget 的创建和销毁,可以显著提高性能。
- Flutter 的渲染管道非常强大。 通过直接操作
RenderObject
,可以实现高度可定制的解决方案。 - 违反 Flutter 的封装原则需要谨慎。 虽然它可以提供灵活性,但它也可能导致意外后果。
解决方法
基于这些发现,我提出了一种新的 ListView 复用解决方案,称为 ReusableListView
。该解决方案结合了手动管理 widget 生命周期和直接操作渲染管道。它既高效又灵活,适用于各种场景。
实现
ReusableListView
的实现相对简单。它使用 CustomScrollView
和 SliverFillViewport
作为基础,并通过一个自定义 RenderObject
来管理 widget 生命周期。这个 RenderObject
跟踪列表项的可见性,并在必要时创建或销毁它们。
性能
为了评估 ReusableListView
的性能,我进行了一系列基准测试。结果表明,ReusableListView
在处理大数据集时比 Flutter 的内置解决方案快得多。
限制
尽管 ReusableListView
性能优异,但它也有几个限制:
- 它不适用于所有场景,例如具有复杂布局的列表项。
- 它需要对 Flutter 的内部工作原理有基本的了解。
结论
虽然 Flutter 的内置 ListView 复用解决方案已经很不错了,但我相信 ReusableListView
提供了更高级别的性能和灵活性。通过手动管理 widget 生命周期和直接操作渲染管道,ReusableListView
可以显着提高列表视图的大数据集处理性能。