简体   繁体   English

StatelessWidget 与在性能方面返回 Widget 的函数

[英]StatelessWidget vs a function returning Widgets in terms of performance

Is there any difference, performance wise, in using a StatelessWidget vs a function returning a Widget ?在性能方面,使用StatelessWidgetfunction returning a Widget有什么区别吗?

I'm well aware of at least the differences pointed out in this flutter's repo issue which don't have a relationship with performance.我很清楚至少在这个颤振的回购问题中指出的差异与性能没有关系。

The fact is that I have some colleagues claiming that functional widgets are worst in terms of performance but after reading a little bit about the subject I cannot find any conclusive piece of documentation that can give credit to that assertion so any kind of clarification regarding this matter will be very welcome!事实是,我有一些同事声称functional widgets在性能方面最差,但是在阅读了一些关于该主题的内容后,我找不到任何可以证明该断言的结论性文档,因此对此问题进行任何形式的澄清会很受欢迎!

As far as I can see the only difference between them would be in the case of using a const Widget , which seems that would avoid the rebuilding phase.据我所知,它们之间的唯一区别在于使用const Widget的情况,这似乎可以避免重建阶段。

First of all, I'd like to note that a package is available to make a StatelessWidget from a function: functional_widget首先,我想指出一个包可用于从函数中创建StatelessWidgetfunctional_widget


The gain is performance is not necessarily true.增益是性能不一定是真的。 It depends on how you use your widgets, mostly how you use them to manage your state.这取决于你如何使用你的小部件,主要是你如何使用它们来管理你的状态。

By default, classes may degrade performances when opposed to functions in an application that doesn't utilize their power.默认情况下,与应用程序中不利用其功能的函数相比,类可能会降低性能。

The real question is: What is their power?真正的问题是:他们的力量是什么?

Simple: Classes can update independently from each other.简单:类可以相互独立更新。 Functions cannot函数不能

It is possible for classes to partially update the widget tree.类可以部分更新小部件树。

Consider a widget that rebuilds every frame and returns its child:考虑一个重建每一帧并返回其子级的小部件:

class InfiniteLoop extends StatefulWidget {
  const InfiniteLoop({Key key, this.child}) : super(key: key);
  final Widget child;
  @override
  _InfiniteLoopState createState() => _InfiniteLoopState();
}

class _InfiniteLoopState extends State<InfiniteLoop> {
  @override
  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));

    return widget.child;
  }
}

Now if we wrap our whole application in that widget, what happens?现在,如果我们将整个应用程序包装在那个小部件中,会发生什么?

void main() => runApp(InfiniteLoop(child: MyApp()));

Nothing没有什么

Sure, you'll have one widget that rebuilds often in your tree.当然,您将拥有一个经常在您的树中重建的小部件。 But in reality, the build method of MyApp will be called only once.但实际上, MyAppbuild方法只会被调用一次。

That's because Flutter is able to abort the tree rebuild when the instance of a widget doesn't change.这是因为 Flutter 能够在小部件的实例没有改变时中止树的重建。


Classes can abuse of this optimization.类可以滥用这种优化。

Using classes it is possible to cleverly split the rebuilding of your widget tree into independent parts.使用类可以巧妙地将小部件树的重建拆分为独立的部分。

It's not reasonable to list all the potential optimization factors that a class allow, as there are too many.列出一个类允许的所有潜在优化因素是不合理的,因为太多了。

The following example is a widget that takes an int and formats it into a Text .以下示例是一个小部件,它采用int并将其格式化为Text The catch is, this widget will rebuild only if the int passed change:问题是,只有int通过更改时,此小部件才会重建:

class Counter extends StatelessWidget {
  const Counter({Key key, this.value}) : super(key: key);

  final int value;

  @override
  Widget build(BuildContext context) {
    return Text(value.toString());
  }

  @override
  bool operator ==(Object other) =>
      identical(this, other) || (other is Counter && other.value == value);

  @override
  int get hashCode => value.hashCode;
}

This works because Flutter uses the == operator to know if a widget should update or not (hence why const constructor is a good optimization factor).这是有效的,因为 Flutter 使用==运算符来了解小部件是否应该更新(因此为什么const构造函数是一个很好的优化因素)。

This is not the only solution, but it's a good example of something that functions can't do.这不是唯一的解决方案,但它是函数无法完成的一个很好的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM