微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Dart 2 / Flutter 中使用 `const` 使用“实例化”对象时有什么性能提升?

如何解决在 Dart 2 / Flutter 中使用 `const` 使用“实例化”对象时有什么性能提升?

在 Dart 2 中,不再需要关键字 newconst 来实例化对象。例如,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(), 小部件(意味着它只会被构建一次)。您可以猜到,这是您可以执行的非常简单但很重要的性能优化。使用常量构造函数不仅仅是我的话,而是文档官方推荐的:

请注意,如果您的小部件包含依赖于 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 举报,一经查实,本站将立刻删除。