【问题标题】:Flutter random slowdowns颤动随机减速
【发布时间】:2021-11-01 13:17:12
【问题描述】:

最近我用颤振构建了一个(生产)应用程序。在最后一个阶段,我深入分析了我的应用程序的性能,因为我注意到偶尔会变慢(fps 会在几秒钟内下降到 30-ish,然后才会再次恢复以变得活泼)。在进行了一些挖掘和剥离功能以首先检查我的断言之后,我一直回到一个简单的应用程序,就像一个仅显示 100 个带有颜色的容器的列表(实际上没有其他内容),即使我的应用程序是这个 '简单',我仍然得到这些减速。一个应用程序真的不能比这更简单(现在大多数应用程序都是列表),所以我想知道其他人是否也有这个问题。这有点烦人,因为当应用程序变慢时它看起来真的很糟糕,而且根据我的研究判断,这似乎是在颤振引擎本身内部,而不是我可以控制的。

这是应用程序,只需将其放在 main.dart 中并自己查看:

main() {
  runApp(
    MaterialApp(
      title: 'my app',
      home: ListView.separated(
        itemCount: 100,
        itemBuilder: (context, index) {
          return Container(
            color: [
              Colors.red,
              Colors.orange,
              Colors.yellow,
              Colors.orange
            ][index % 4],
            height: 200,
          );
        },
        separatorBuilder: (context, index) => const SizedBox(height: 30),
      ),
    ),
  );
}

请注意,这种情况只是偶尔发生,只需继续并在查看性能监视器时滚动一下即可查看帧时间。应该偶尔出现单个高条,并且时不时地(比如每两次滚动列表一次)会有几秒钟的长帧时间(由 Flutter 的分析器索引为“Jank(慢帧)” /vscode)。

我在跑步:

  • 颤振:2.5.3
  • 飞镖:2.14.4。
  • 物理测试设备:iPhone 12 Pro
  • 配置文件模式

我的启动设置(vscode)

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Flutter",
      "request": "launch",
      "type": "dart",
      "flutterMode": "profile",
      "args": []
    }
  ]
}

TL;DR 我有一个“尽可能简单”的颤振项目,它只显示一个长列表(单元重用,因为它是 ListView.builder),尽管简单,但经常出现滞后峰值和帧丢失(长“光栅”时间) . Flutter 医生没有表现出什么特别的地方

实际问题 其他人也有这个问题吗?有谁知道在哪里可以找到这个卡顿的真正原因?

【问题讨论】:

  • 以防万一,我假设您在设备上以配置文件模式运行应用程序(而不是调试模式)?在调试模式下,某些功能的处理方式不同,导致它在不在实际场景中时会出现问题(我确定这是在 Android 中发生的事情,我对 iOS 不是 100% 确定)
  • 没错,我会用我的 launch.json (vscode) 更新帖子

标签: flutter performance-testing


【解决方案1】:

我刚刚在我自己的设备(小米米 A2、Android 10)上运行了您的代码,并且无法在 DevTools 中获得任何卡顿帧(即使滚动速度非常快)。

由于手机很便宜,我之前也遇到过一些卡顿的动画,但在这种情况下没有什么可说的。

上网查了一下,确实遇到了几个类似的问题,其中一个也讨论了可能是因为listview事先不知道元素的大小造成的:https://github.com/flutter/flutter/issues/52207

提高性能的一种方法似乎是使用具有固定范围的 SliverList(标准 ListView 也在后台使用):https://api.flutter.dev/flutter/widgets/SliverFixedExtentList-class.html

当然,这仅在您的所有子列表都具有相同的固定大小时才有效(您的示例就是这种情况,但可能不适用于您的实际应用程序)。

调整您的代码,您将使用如下内容:

main() {
  runApp(
    MaterialApp(
      title: 'my app',
      home: CustomScrollView(
        slivers: [
          SliverFixedExtentList(
              delegate: SliverChildBuilderDelegate((context, index) {
                return Column(
                  children: [
                    Container(
                      color: [
                        Colors.red,
                        Colors.orange,
                        Colors.yellow,
                        Colors.orange
                      ][index % 4],
                      height: 200,
                    ),
                    SizedBox(
                      height: 30,
                    ),
                  ],
                );
              }, childCount: 100),
              itemExtent: 230),
        ],
      ),
    ),
  );
}

如果这可以改善您设备上的情况,您可以尝试

【讨论】:

  • 感谢您的提示!是的,不幸的是,我的应用程序需要动态大小的单元格,因此不能选择使用 SliverList。然而,我确实在一个新生成的颤振应用程序中对其进行了测试,以查看与使用 ListView.builder 的区别,不幸的是行为保持不变。我时不时地(大约每 5 秒滚动一次)看到一个长条(在非常低的帧时间之间),偶尔,但这可能需要相当长的时间(比如有时滚动 2 分钟)一堆慢帧.我怀疑它也可能是 iOS 简单地“管理/分配”cpu 资源..
猜你喜欢
  • 1970-01-01
  • 2011-01-31
  • 2010-12-11
  • 2022-08-19
  • 1970-01-01
  • 2010-12-16
  • 2023-02-06
  • 1970-01-01
  • 2019-10-07
相关资源
最近更新 更多