创建窗口小部件树时,在静态窗口小部件之前插入const
会提高性能吗?
即
child: const Text('This is some text');
vs
child: Text('This is some text');
我知道,在Dart 2中,const
是可选的,并且在某些地方会自动插入。这是其中一种情况吗?如果不是,使用const
会减少内存使用/提高性能吗?
感谢您的回答!
答案 0 :(得分:4)
我已经进行了一些测试,看是否有帮助。
这些测试很大程度上取决于在this article中进行的测试。
对于测试,有300个容器,其中文本在屏幕上随机移动。您在日常应用中看不到的东西。
对于我的结果,每秒帧数没有差异,内存使用也没有差异,只是垃圾回收器在不使用const时似乎更频繁地运行。同样,FPS大致相同。
Imo,性能提升可忽略不计,听起来像抢先式优化。但是,在测试中没有嵌套的小部件链,但是我不认为这会有什么不同。上面的文章似乎说只有一小段,但这不是我的测试所显示的。
我有一张这样的卡片(这是const版本):
import 'package:flutter/material.dart';
class MyCard extends StatelessWidget {
const MyCard();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
margin: const EdgeInsets.all(8.0),
height: 100,
width: 100,
color: Colors.red,
child: const Text('Hi'),
),
);
}
}
可以渲染300次并在屏幕上随机移动。
这是使它们移动的小部件
import 'package:flutter/material.dart';
import 'dart:math';
import 'dart:async';
import './my-card.dart';
class MovingContainer extends StatefulWidget {
@override
_MovingContainerState createState() => _MovingContainerState();
}
class _MovingContainerState extends State<MovingContainer> {
final Random _random = Random();
final Duration _duration = const Duration(milliseconds: 1000);
Timer _timer;
double _top = 0;
double _left = 0;
@override
void initState() {
super.initState();
initMove();
}
void initMove() {
_timer = Timer.periodic(
_duration,
(timer) {
move();
},
);
}
void move() {
final Size size = MediaQuery.of(context).size;
setState(() {
_top = _random.nextInt(size.height.toInt() - 100).toDouble();
_left = _random.nextInt(size.width.toInt() - 100).toDouble();
});
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedPositioned(
top: _top,
left: _left,
child: const MyCard(),
duration: _duration,
);
}
}
注意:我是扑朔迷离的新手,所以还有很多其他人,因为这是一个相对较新的框架。因此,我的测试很可能是错误的,请不要将其视为福音。当您阅读题为《 Flutter的第一性能收益》的文章时,也不要把它当作福音。我还没有看到实际的证明,这是有好处的。抢先式优化是一个很好的谬论。
答案 1 :(得分:3)
在Flutter的情况下,const
的实际增益是 not 实例化较少。
当窗口小部件的实例不变时,Flutter进行了特殊处理:它不会重建它们。
请考虑以下内容:
Foo(
child: const Bar(
child: Baz()
),
)
如果再次调用build
方法(setState
,父级重建,Inheritedwidget
...),则由于{{1} }子树,只有const
会看到其Bar
方法被调用。
Foo
永远不会因为其父对象而被重建,因为Flutter知道,由于小部件实例没有变化,因此没有任何更新。
答案 2 :(得分:2)
这是一个很小的性能改进,但是它可以添加到较大的应用程序或经常由于例如动画而重建视图的应用程序中。
const
减少了垃圾收集器所需的工作。
您可以在analysis_options.yaml
中启用一些linter规则,这些规则会告诉您何时应添加const
,因为它不是可以推断的,但是可能会像这样
或者它会在您使用const
时提醒您,但还是可以推断出
另请参阅https://www.dartlang.org/guides/language/analysis-options