Flutter开发过程中DevTools一些心得

DevTools是什么

DevTools是Flutter开发过程中调试应用和性能调优过程中使用到的工具集合。主要作用是监察UI布局,监察CPU使用情况,监察内存使用情况,监察网络使用情况等等。帮助开发者诊断UI卡顿,分析UI各个阶段的耗时情况,量化各个阶段或者方法调用的耗时,以及内存使用情况的量化可视化,方便以及协助开发者定位解决问题。高效开发离不开高效的工具。工欲善其事,必先利其器。其实就是这个道理。

查看应用的信息

DevTools的一个标签Flutter DevTools显示配对的应用的信息,如设备CPU以及系统信息,Dart和Flutter版本信息,以及Flutter Framework以及Engine版本信息。如下图所示:

Flutter inspector

Flutter inspector是一个可视化和探索Widget树的工具,只有在debug模式下才能够显示,在Profile模式下不能显示。选中Highlight Repaints标签,此选项在所有渲染框周围绘制一个边框,该边框每次重新绘制时都会改变颜色。 例如,一个小动画可能会导致整个页面在每一帧上重新绘制。将动画包装在RepaintBoundary Widget中可将重新绘制限制为动画。此处进度指示器导致其容器重新绘制:

scala 复制代码
class EverythingRepaintsPage extends StatelessWidget {
  const EverythingRepaintsPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Repaint Example')),
      body: const Center(
        child: CircularProgressIndicator(), //此Widget可以用RepaintBoundary包裹
      ),
    );
  }
}

RepaintBoundary widget为其Widget创建一个单独的显示列表,如果子树的重新绘制时间与树的周围部分不同,这可以提高性能。如果RepaintBoundary的子树中有多个动画的组合使用,会提高性能,减少多余的刷新次数。RepaintBoundary Widget同样也有其弊端,它们可以帮助提高性能,但也需要创建新画布,这会占用额外的内存。

图片占用比较大的内存,所以图片在内存中的使用情况是一个不得不考虑的性能问题。

csharp 复制代码
void showOversizedImages() {
  debugInvertOversizedImages = true;
}

debugInvertOversizedImages设置为true,或者选中Flutter inspector页面的Highlight Oversized Images标签,不合理的图片使用情况会显示出来。图片宽高过大,导致图片编解码显示时间增大,同时导致内存占用过多,如果图片过多可能会导致内存溢出,导致应用稳定性减弱,引起应用崩溃。

  1. 最好的处理方式是缩小图片的宽高,并且把图片资源放到Asset Image资源中,图片显示最新缩小的图片。
  2. 稍好的处理Image Widget显示图片的时候设置cacheHeight和cacheWidth参数。
  3. 迫不得已可以使用ResizeImage Widget。

Memory

内存的使用情况可以通过上面的视图可以查看。内存视图可以提前发现如下几种类型的问题:

  1. 耗尽内存导致的崩溃。
  2. 超过系统存储限制导致的崩溃。
  3. 因为可用内存过少引起频繁的垃圾回收,导致的应用反应缓慢,甚至导致不反应的情况。
  4. 内存泄漏。

内存泄漏就像一个慢慢滴落的水龙头。起初它似乎并不重要,但随着时间的推移,它可能会导致大量问题,从而降低应用程序的性能。

简单介绍一下Dart和Flutter的内存。根对象:每个Dart应用程序都会创建一个根对象,该根对象直接或间接引用应用程序分配的所有其他对象。垃圾回收算法(可达性回收算法):如果在应用程序运行的某个时刻,根对象停止引用已分配的对象,则该对象将变得无法访问,这是垃圾收集器(GC)释放对象内存的信号。Java也使用根对象到对象之间的链路是否连接来确定对象能否被回收。对象与根对象之间有链接通路是对象没有被回收的根本原因,这就是内存泄漏的本质。内存泄漏是属于开发方面的编码错误,VM(虚拟机)无法避免。长生命周期的对象持有短生命周期的对象也是内存泄漏的一个类型。如何检测内存泄漏呢,如下图所示:

  1. Memory页面中有Diff Snapshots标签页,选中。
  2. 不同时刻点击两次记录内存快照按钮,生成两次内存快照。
  3. 选中两次内存快照,进行Diff with,分析是否有内存泄漏情况。

避免Flutter中内存泄漏的一般技巧:

  • 调用相应Controller的dispose方法。例如AnimationController、TextEditingController、StreamController等。
  • 取消订阅:取消对流或其他异步操作的任何有效订阅(资源的及时关闭)。
  • 删除侦听器:当不再需要时,删除附加到各种组件的侦听器(例如,事件侦听器)。
  • 避免保留大对象:除非绝对必要,否则请避免在小部件中保留对大对象的引用。
  • 使用弱引用:在某些情况下,使用弱引用可以帮助防止内存泄漏,因为它允许在不再需要对象时对其进行垃圾回收。

Performance

查看某一帧各个阶段的耗时,在Flutter Frames选择图表中的一组,查看耗时。如下图所示,如UI阶段的耗时,以及Raster阶段的耗时。如果视图中出现红色的一组Frame,就应该关注分析这组Frame出现耗时过长的原因。 通过Android Studio的Profiler工具可以查看,绘制和渲染相关的线程包括ui线程和raster线程,执行的动图如下图所示:

总结

性能是一个调优是一个复杂而艰巨的任务,不仅需要对Dar和Flutter的知识体系有完整而深刻地认识,同时需要工具的高效配合。Flutter的DevTools就是为了解决Debug和性能调优而开发出来的工具,学好这个相关的知识之后,不仅能够开发出性能优异的应用;遇到相关的渲染的bug和性能问题,也能够游刃有余地迅速解决。知其然,知其所以然,其实就是这个道理。学习技术,我觉得应该需要"打破砂锅问到底"的劲头,同样也需要精益求精的工匠精神。应用会朝着更小,更快,更省发展。

致谢

性能调优有很多方面可以做,本文仅仅简单讲了三方面的科普,内存,性能和UI监察。希望文章对大家有所帮助,如果文章有所纰漏请不吝指教,大家共同进步。欢迎关注"技术蔡"的公众号,此公众号也是本作者的技术相关的公众号。

参考资料

docs.flutter.dev/tools/devto...

www.youtube.com/watch?v=cVA...

相关推荐
夏目艾拉7 小时前
flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)
android·java·flutter·设计模式
AiFlutter13 小时前
Flutter的升级和降级步骤
flutter
cola_wh13 小时前
flutter的入口和原生交互
flutter
Flutter鸿蒙梁典典学院13 小时前
Flutter自动打包ios ipa并且上传
flutter·ios·cocoa
Jack魏13 小时前
Android Studio 2024最新版Hello World
android·android studio·安卓
码农下的天桥1 天前
Android studio 导出 release 版本的 .aar 文件
android·ide·android studio
Nadeal1 天前
Flutter 创建项目时指定原生项目编程语言
flutter
xiaaaa.z1 天前
【Flutter】Flutter安装和配置(mac)
flutter·macos
cuisidong19972 天前
Java DAO 层:数据访问对象模式解析与实践
android·ide·android studio
zh路西法2 天前
基于Android Studio的行程记录APK开发指南(二):熟悉一个项目结构
android·ide·kotlin·android studio