【问题标题】:Flutter chat list update rebuild efficiencyFlutter 聊天列表更新重建效率
【发布时间】:2021-05-11 11:12:21
【问题描述】:

我是 Flutter 的新手,我正在尝试构建一个聊天应用程序,我已经看过几个教程。要查看聊天消息列表/历史记录,几乎每个教程都在做这样的事情:(我正在缩短代码以达到重点)

List<Widget> messages = api.listOfMessages();

return Column(children: messages);

现在每次有新消息时,messages 都会更新并重新构建该列。我得说“重建”这个词对我来说听起来很昂贵。假设 2 个用户一直在聊天 500 行。现在,每次收到新消息时,都会重新构建 500 行。

我考虑在列表末尾放置一个空小部件。因此,当有新消息到达时,我只需将其插入到那个空的小部件中,然后只重建它:

List<Widget> messages = api.listOfMessages();

return Column(children: [...messages, EmptyWidgetForNewMessage()];

但这看起来像一个 hack,会导致很多嵌套的小部件,因为每条新消息还必须插入另一个 EmptyWidget 等......

如何避免重建以前的消息而只将新消息插入视图? (或者重建整个列表没什么大不了的?)

【问题讨论】:

    标签: flutter chat rebuild


    【解决方案1】:

    您可以使用 sliver 小部件构建在视口中(或在 cacheExtent 中)可见的消息。 喜欢ListView.buildListView.separated,来自ListView.build的文档:

    如果列表视图的孩子是 预先创建,或者在创建 [ListView] 本身时一次性创建, 使用 [ListView] 构造函数更有效。然而,更有效的是使用此构造函数的 itemBuilder 回调按需创建实例。

    此外,我们不会一次从服务器获取所有消息。相反,我们将使用 ?page=1&amp;size=20 之类的查询分批获取它们。

    注意:此小部件存在一个已知问题,请尽可能避免使用 shrinkWrap: true。见this issue

    【讨论】:

      【解决方案2】:

      您可以针对的几个改进

      1. 使用ListView builder 构造函数而不是列,只会渲染当前在屏幕中可见的子小部件,而在Column 小部件中将渲染其所有子小部件。另外ListView 应该是您的首选小部件,因为Column 小部件不可滚动,并且如果消息列表长度很大,则可能会出现溢出异常。

      2. api.listOfMessages()返回的所有类型的小部件使用const构造函数,这将允许编译器重用任何渲染的小部件,这意味着每次发生状态变化时(在你的情况下,新消息的到达)整个树不会重新渲染,渲染器将可以重新使用以前构建的消息小部件。

      这两个建议应该解决任何性能瓶颈,简而言之,我们将仅使用 ListView 渲染可见的子小部件,并且我们将在 const 构造函数的帮助下重用已渲染的小部件。

      【讨论】:

        猜你喜欢
        • 2021-08-25
        • 1970-01-01
        • 2021-05-26
        • 1970-01-01
        • 1970-01-01
        • 2016-09-19
        • 1970-01-01
        • 1970-01-01
        • 2018-08-05
        相关资源
        最近更新 更多