如何解决Flutter 聊天列表更新重建效率
我是 Flutter 的新手,我正在尝试构建一个聊天应用程序,我看过几个教程。要查看聊天消息列表/历史记录,几乎每个教程都在做这样的事情:(我正在缩短代码以切入要点)
List<Widget> messages = api.listofMessages();
return Column(children: messages);
现在每次有新消息时,都会更新 messages
并重新构建列。我得说“重建”这个词对我来说听起来很昂贵。假设 2 个用户已经聊天 500 行。现在,每次收到新消息时,都会重新构建 500 行。
我想在列表的末尾放一个空的小部件。因此,当新消息到达时,我只需将其插入到那个空的小部件中,然后只重建它:
List<Widget> messages = api.listofMessages();
return Column(children: [...messages,EmptyWidgetForNewMessage()];
但这看起来像一个黑客,会导致很多嵌套的小部件,因为每条新消息还必须插入另一个 EmptyWidget 等...
如何避免重建以前的消息而只将新消息插入到视图中? (或者重建整个列表没什么大不了的?)
解决方法
您可以使用 sliver 小部件构建在视口(或 cacheExtent)中可见的消息。
像 ListView.build
,ListView.separated
,来自 ListView.build
的文档:
如果列表视图的子视图是
提前创建,或者在创建 [ListView] 本身时一次性创建,
使用 [ListView] 构造函数更有效。然而,更有效的是使用此构造函数的 itemBuilder
回调按需创建实例。
此外,我们不会一次从服务器获取所有消息。相反,我们将使用 ?page=1&size=20
之类的查询批量获取它们。
注意:此小部件存在一个已知问题,请尽可能避免使用 shrinkWrap: true
。见this issue
您可以针对的几个改进
-
使用
ListView
构建器构造函数而不是列,只会呈现当前在屏幕中可见的子小部件,而在Column
小部件中,将呈现其所有子小部件。此外,ListView
应该是您首选的小部件,因为Column
小部件不可滚动,如果消息列表长度很大,则可能会出现溢出异常。 -
对
const
返回的所有类型的小部件使用api.listOfMessages()
构造函数,这将允许编译器重用任何呈现的小部件,这意味着每次发生状态更改时(在你的情况下到达新消息)整个树不会重新渲染,渲染器将可以重新使用以前构建的消息小部件。
这两个建议应该可以解决任何性能瓶颈,简而言之,我们将仅使用 ListView 呈现可见的子小部件,并且我们将在 const
构造函数的帮助下重用已呈现的小部件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。