StatelessWidget与在性能方面返回Widget的函数 [英] StatelessWidget vs a function returning Widgets in terms of performance
问题描述
在性能方面,使用StatelessWidget
与function returning a Widget
有什么区别吗?
Is there any difference, performance wise, in using a StatelessWidget
vs a function returning a Widget
?
我至少知道 flutter的回购中指出的差异问题与性能没有关系.
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.
事实是,我有一些同事声称functional widgets
在性能方面是最差的,但是在阅读了一些有关该主题的知识后,我找不到任何可以归结于该断言的结论性文件,因此任何种类的关于此事的澄清将非常受欢迎!
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!
据我所知,它们之间的唯一区别在于使用const Widget
的情况,这似乎可以避免重建阶段.
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.
推荐答案
首先,我想指出一个包可用于通过函数制作StatelessWidget
:
First of all, I'd like to note that a package is available to make a StatelessWidget
from a function: functional_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
类可能会部分更新小部件树.
考虑一个可重建每一帧并返回其子级的小部件:
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()));
没事
当然,您将拥有一个经常在树中重建的小部件.但实际上,MyApp
的build
方法将仅被调用一次.
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.
那是因为当窗口小部件的实例不变时,Flutter能够中止树的重建.
That's because Flutter is able to abort the tree rebuild when the instance of a widget doesn't change.
班级可能会滥用此优化.
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.
下面的示例是一个小部件,它使用int
并将其格式化为Text
.问题是,如果int
通过了更改,则此窗口小部件将仅重建 :
The following example is a widget that takes an int
and formats it into a Text
. The catch is, this widget will rebuild only if the int
passed change:
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;
}
之所以可行,是因为Flutter使用==
运算符来知道小部件是否应该更新(因此,为什么const
构造函数是一个很好的优化因素).
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).
这不是唯一的解决方案,但这是函数无法完成的一个很好的例子.
This is not the only solution, but it's a good example of something that functions can't do.
这篇关于StatelessWidget与在性能方面返回Widget的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!