创建小部件树时,在静态小部件之前插入const是否会提高性能?即
const
child: const Text('This is some text');
对比
child: Text('This is some text');
我知道,在Dart 2中,const是可选的,并且会在某些地方自动插入。这是其中一种情况吗?如果不是,使用const是否会减少内存使用/提高性能?
oknrviil1#
这是一个很小的性能改进,但它可以在较大的应用程序或视图经常重建的应用程序中(例如,由于动画)累积起来。const减少了垃圾收集器所需的工作。您可以在analysis_options.yaml中启用一些linter规则,这些规则告诉您应该何时添加const,因为它不是推断的,而是可能的,例如
analysis_options.yaml
或者在使用const时提醒您,但无论如何都是推断的
另请参见https://www.dartlang.org/guides/language/analysis-options
idv4meu82#
在Flutter的例子中,const的真正好处是"不"具有更少的示例化。Flutter对小部件的示例不改变有一个特殊的处理:它不能重建它们。请考虑以下几点:
Foo( child: const Bar( child: Baz() ), )
在build方法被再次调用的情况下(setState、父重建、Inheritedwidget ...),则由于Bar子树的const,只有Foo将看到其build方法被调用。Bar将 * 永远 * 不会因为其父对象而被重新构建,因为Flutter知道,既然小部件示例没有更改,就没有什么要更新的。
build
setState
Inheritedwidget
Bar
Foo
kpbwa7wx3#
**更新:**我注意到最近我收到了一个赞成票,我必须说我对下面的测试没有信心,但这就是我得到的全部。所以最好有人运行一个更好的测试。
我做了些测试看看有没有影响。这些测试主要基于在this article中完成的测试。在测试中,有300个容器,里面的文本在屏幕上随机移动,这是你在日常应用程序中看不到的。对于我的结果来说,每秒帧数没有差别,内存使用也没有差别,除了垃圾收集器在不使用常量时似乎运行得更频繁。
我的意思是,性能提升是微不足道的,听起来像是抢先优化。然而,在测试中没有嵌套的小部件链,但我不认为这会有什么不同。上面的文章似乎说有一个小的,但这不是我的测试显示。我有一张这样的卡片(这是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的新手,其他人也是,因为它是一个相对较新的框架。因此,我的测试很可能是错误的,不要把它当作福音。当你读到一篇名为《头号性能增益在Flutter上》的文章时,也不要把它当作福音。我还没有看到实际的证据证明有性能增益。
m1m5dgzv4#
当我们使用setState()时,Flutter调用build方法并重建其中的每个小部件树,避免这种情况的最好方法是使用const构造函数。在构建自己的小部件或使用Flutter小部件时,尽可能使用const构造函数。这有助于Flutter只重新构建应该更新的小部件。因此,如果您有一个StatefulWidget,并且使用setState((){})更新该小部件,那么您有如下小部件:
class _MyWidgetState extends State<MyWidget> { String title = "Title"; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Column( children: <Widget>[ const Text("Text 1"), const Padding( padding: const EdgeInsets.all(8.0), child: const Text("Another Text widget"), ), const Text("Text 3"), ], ), floatingActionButton: FloatingActionButton( child: const Icon(Icons.add), onPressed: () { setState(() => title = 'New Title'); }, ), ); } }
4条答案
按热度按时间oknrviil1#
这是一个很小的性能改进,但它可以在较大的应用程序或视图经常重建的应用程序中(例如,由于动画)累积起来。
const
减少了垃圾收集器所需的工作。您可以在
analysis_options.yaml
中启用一些linter规则,这些规则告诉您应该何时添加const
,因为它不是推断的,而是可能的,例如或者在使用
const
时提醒您,但无论如何都是推断的另请参见https://www.dartlang.org/guides/language/analysis-options
idv4meu82#
在Flutter的例子中,
const
的真正好处是"不"具有更少的示例化。Flutter对小部件的示例不改变有一个特殊的处理:它不能重建它们。请考虑以下几点:
在
build
方法被再次调用的情况下(setState
、父重建、Inheritedwidget
...),则由于Bar
子树的const
,只有Foo
将看到其build
方法被调用。Bar
将 * 永远 * 不会因为其父对象而被重新构建,因为Flutter知道,既然小部件示例没有更改,就没有什么要更新的。kpbwa7wx3#
**更新:**我注意到最近我收到了一个赞成票,我必须说我对下面的测试没有信心,但这就是我得到的全部。所以最好有人运行一个更好的测试。
我做了些测试看看有没有影响。
这些测试主要基于在this article中完成的测试。
在测试中,有300个容器,里面的文本在屏幕上随机移动,这是你在日常应用程序中看不到的。
对于我的结果来说,每秒帧数没有差别,内存使用也没有差别,除了垃圾收集器在不使用常量时似乎运行得更频繁。
我的意思是,性能提升是微不足道的,听起来像是抢先优化。然而,在测试中没有嵌套的小部件链,但我不认为这会有什么不同。上面的文章似乎说有一个小的,但这不是我的测试显示。
我有一张这样的卡片(这是const版本):
它被渲染了300次,并在屏幕上随机移动。
这是一个让它们移动的小工具
注意:我是flutter的新手,其他人也是,因为它是一个相对较新的框架。因此,我的测试很可能是错误的,不要把它当作福音。当你读到一篇名为《头号性能增益在Flutter上》的文章时,也不要把它当作福音。我还没有看到实际的证据证明有性能增益。
m1m5dgzv4#
当我们使用setState()时,Flutter调用build方法并重建其中的每个小部件树,避免这种情况的最好方法是使用const构造函数。
在构建自己的小部件或使用Flutter小部件时,尽可能使用const构造函数。这有助于Flutter只重新构建应该更新的小部件。
因此,如果您有一个StatefulWidget,并且使用setState((){})更新该小部件,那么您有如下小部件: