【问题标题】:Which is efficient? Flutter StreamBuilder Widget vs Stream.Listen() with setState()哪个高效? Flutter StreamBuilder Widget vs Stream.Listen() with setState()
【发布时间】:2021-07-12 18:36:25
【问题描述】:

我正在编写一个持续时间为 1 秒的周期性流来显示时间:

stream: Stream.periodic(Duration(seconds: 1)),
builder: (context, snapshot) {
  return Text(DateTime.now().toString());
}

另外,我可以通过以下方式实现相同的目标:

Stream.periodic(Duration(seconds: 1)).listen((){
setState(){});

也是。

我想知道,哪种方法更有效?
流生成器每秒返回一个小部件或在其他情况下返回一个小部件树。而setState() 在我的情况下重建整个应用程序小部件树。我在这里很困惑。请指教。

【问题讨论】:

  • devtools 能有更准确的答案吗?
  • @pskink 现在似乎提出了在 StreamBuilder 内使用 StatefulBuilder 的问题,StreamBuilder 将每秒返回 StatefullBuilder。另外,为什么我们需要每秒钟设置一次状态,因为我已经在 StreamBuilder 的范围内拥有了 fields。无论如何。开放讨论。
  • 我不想避免它,但我对这两种方法的性能感到好奇,(StreamBuilder vs Stream.listen(setState(){}))在我的特殊情况下。 @ambiguous58 在下面指出了一些有用的提示。

标签: flutter dart widget stream-builder


【解决方案1】:

setState 不会重建整个应用小部件树。您提到的两种方法(StreamBuilder 和 Stream.listen)都会在有新事件时重建自己及其后代。

如果您的整个应用程序都在一个大的build 方法下,那么是的setState 将触发重建它所在的build 方法。如果是这种情况,您应该出于性能原因拆分代码。

official StatefulWidget docs 中实际上提到了您的用例。

将状态推送到叶子。例如,如果您的页面有一个滴答作响的时钟,而不是将状态放在页面顶部并在每次时钟滴答时重建整个页面,请创建一个仅更新自身的专用时钟小部件。

此外,您始终可以利用devtools 来衡量任何性能差异。

【讨论】:

  • 因此,在这种情况下使用StreamBuilder 似乎等同于dedicated clock widget。对吗?
【解决方案2】:

我认为第一种方法更有效,因为当事件发生时它只会触发该流的构建。

但是调用setState() 将重建有状态小部件的整个小部件树.. 所以成本更高

【讨论】:

  • 我不认为这是准确的,因为 OP 提到的两种方法(StreamBuilder 和 Stream.listen)都会在有新事件时重建自己及其后代。
  • 是的,StreamBuilder 的后代在第一种情况下将被重建,但在第二种情况下,它调用 setState() 将重建整个小部件树,甚至在需要重建的小部件之上
  • setState 仅重建它所在的 build 方法。因此,如果整个应用程序都在一个大的 build 方法下,那么是的,它将被重建。 *颤抖*
  • 是的,这正是我的意思,如果您在 column 中可能有多个流构建器,那么最好使用第一种方法,因为它会根据其状态构建每一个。
猜你喜欢
  • 1970-01-01
  • 2019-01-19
  • 1970-01-01
  • 2020-12-11
  • 2021-02-20
  • 1970-01-01
  • 2019-12-26
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多