如何解决在 Dart 2 / Flutter 中使用 `const` 使用“实例化”对象时有什么性能提升?
在 Dart 2 中,不再需要关键字 new
和 const
来实例化对象。例如,new ListView(...)
现在等同于 ListView(...)
。
但是,一些类构造函数声明为 const
,包括大多数 Flutter 小部件,例如 Text
:
const Text(
String this.data,{
Key? key,this.style,// ...
this.textHeightBehavior,})
然后,要实例化 Text
,我们可以键入 Text('hi!')
或 const Text('hi!')
。
注意:
调用处const
的用法在某些地方比较突出,比如在Android Studio中,如果我们选择“Wrap with Padding”,则EdgeInsets.all
构造函数调用使用{{1 }}:
const
解决方法
如果可能,您应该始终尝试使用 const
,尤其是在您创建 Flutter 应用程序时。常量构造函数非常重要,因为它们用于“缓存”小部件,以便它们不会被不必要地重建。
假设您的 Flutter 应用中有 10k 个项目的列表:
class Example extends StatelessWidget {
const Example();
@override
Widget build(BuildContext context) {
return Column(
children: [
const Text('My items:'),ListView.builder(
shrinkWrap: true,itemCount: 10000,itemBuilder: (_,i) => SomeComplexWidget(
value: i,),],);
}
}
有很多因素可能会触发小部件重建,但我们假设您只是将设备屏幕旋转了几次。使用此代码...
SizedBox(
width: 100,height: 400,child: Example(),
...您没有使用 const
构造函数,因此您在 every 重建时重建 Example
(= 您还不必要地重建了 {{1 }}、Column
和重新渲染一些 ListView
)。 SomeComplexWidget
是一个惰性初始化器,因此它会为您节省一点,但您仍然不希望它总是被重建。
如果您为列表使用 ListView.builder
或普通的 Column()
构造函数,它会对性能产生更大的影响(更多的卡顿和更多的跳帧)。如果你这样做了......
ListView()
...您将“缓存”SizedBox(
width: 100,child: const Example(),
小部件(意味着它只会被构建一次)。您可以猜到,这是您可以执行的非常简单但很重要的性能优化。使用常量构造函数不仅仅是我的话,而是文档官方推荐的:
- StatelessWidget 文档(请参阅性能注意事项)
- StatefulWidget 文档(请参阅性能注意事项)
请注意,如果您的小部件包含依赖于 Example
的内容,则 InheritedWidget
关键字将无效(否则,小部件无法“侦听”继承的小部件上的更改)。
奖金
在 Flutter 中,您还可以“手动”缓存小部件。当您无法使用 const
时,您可以在状态内使用 const
(或 late
)来缓存小部件。看这个例子:
late final
您希望 class OtherExample extends StatelessWidget {
final List<Interests> interests;
const OtherExample({
required this.interests,});
@override
Widget build(BuildContext context) {
return Column(
children: [
const Text('My list'),MyInterestsList(
data: interests,]
);
}
}
被缓存,因为它永远不会改变,但 MyInterestsList
在这里不起作用(因为 const
是不是编译时)常量.当您无法使用 interests
但仍想缓存小部件时,请手动执行:
const
感谢 class OtherExample extends StatefulWidget {
final List<Interests> interests;
const OtherExample({
required this.interests,});
@override
_OtherExampleState createState() => _OtherExampleState();
}
class _OtherExampleState extends State<OtherExample> {
late Widget myInterests = MyInterestsList(
data: widget.interests,);
@override
void didUpdateWidget(OtherExample oldWidget) {
super.didUpdateWidget(oldWidget);
// This makes sure that the interests list is updated ONLY when
// it actually changes
if (widget.interests != oldWidget.interests) {
myInterests = MyInterestsList(
data: widget.interests,);
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
const Text('My list'),myInterests,]
);
}
}
,您将小部件缓存在状态类中。由于 late
覆盖,didUpdateWidget
小部件将仅在列表更改时重建。如果列表永远不会改变,MyInterestsList
将永远不会被重建。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。