Flutter 提供了不少性能分析工具,但感觉相关文档不咋的,散落在官方的各个地方,对开发者不太友好。另外,有的工具目前只在 Android Studio 中有,比如 Flutter Performance;甚至有的工具只在 debug 模式下可用。本文对这些工具简单整理一下,便于做性能优化时查找和参考。
开启 Performance Overlay 有多种方式,最简单的几种包括:
性能图层用两张图表显示应用的耗时信息。每一张图表都代表当前线程的最近 300 帧表现。
更多信息请参考 Flutter 线程
使用 Performance Overlay 可以对 UI 性能问题进行定性分析,大致判断到底是 Dart 代码执行过慢(布局慢)还是场景复杂无法快速渲染(渲染慢)。
Performance Overlay 可用于 profile 模式。
PerformanceOverlay 可以视为 Performance Overlay 的高级版本(Performance Overlay 正是基于 PerformanceOverlay 控件来实现的)。
通过如下方式在代码中开启 PerformanceOverlay
控件。参考。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
showPerformanceOverlay: true,
title: 'My Awesome App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'My Awesome App'),
);
}
}
如果没有使用 MaterialApp
等控件,可以自己调用 PerformanceOverlay.allEnabled(checkerboardOffscreenLayers: true,);
来实现类似效果。
Observatory 是 Dart SDK 提供的用于分析和调试 Dart 程序的工具。可以使用 Observatory 来观察 Dart VM 内部状态,获取应用的实时数据。主要功能包括:
虽然 Observatory 正在被 DevTools 慢慢取代,但某些情况下它提供的性能数据更为详细。
Observatory 的使用步骤:
刷新后可以在事件面板中检查和分析UI线程和GPU的耗时,以定位性能瓶颈。
debugProfileBuildsEnabled
设置为 true
可以在 Observatory 中看到 构建 Widget 的耗时chrome://tracing
然后将 json 文件拖进去时间线视图用于显示 Flutter 帧信息。它由三个部分组成。
使用 Timeline 可以对 UI 性能问题进行定量分析,通过观察布局阶段和渲染阶段的耗时,进一步定位问题原因。
Performance Overlay 可用于 profile 模式。
帧渲染图表跟 Performance Overlay 很类似。
图表中的每个条形框都代表一帧,每帧中不同线程的执行情况以不同颜色表示。
在帧渲染图表中选中一帧后,帧事件图表中将显示具体事件及其耗时。
我们可以从 DevTools Timeline 中导出 timeline 文件。
导出的 timeline 文件可以重新导入到 chrome tracing 进行分析。
chrome tracing 几个常用的操作键包括:
chrome tracing 工具展示如下两个阶段的耗时:
(TODO 如何解读这些数据? 比 CPU 分析器更容易观察数据?)
Timeline 用于向时间线添加同步事件。使用方法很简单:
Timeline.startSync("Doing Something");
doSomething();
Timeline.finishSync();
或者:
Timeline.timeSync("Doing Something", () {
doSomething();
});
我们在代码中添加 “Doing Something”,
然后将 DevTools Timeline 导出的 timeline 文件重新导入到 Chrome Tracing 工具。从中我们可以找到 “Doing Something” 对应的事件,如下图:
Android Studio 中 View > Tool Windows > Flutter Performance 打开性能工具窗口,在 Widget rebuild stats 中勾选 Track widget rebuilds 来查看 widget 的重建信息。重建信息包括 Widget 名字、源码位置、上一帧中重建次数、当前页面中重建次数。此外,Widget 名字前面还会显示一个小图标。
这个功能的目的是让你了解 widget 是何时重建的,如果发生不符合预期的重建,就需要优化代码了。优化方法请参考 StatefulWidget 与性能 (译文见这里)
Widget rebuild profiler 只能用于 debug 模式。
Performance Overlay 使用两张图来表示 UI线程 和 GPU线程的最近 300 帧表现。
不过 FPS 对我们来说更直接。Android Studio Flutter Performance 中可以看到 FPS 值:
我们也可以使用 WidgetsBinding.addTimingsCallback
方法来自行统计 FPS。这里提供两个参考实现:
刚入门 Flutter 开发时,你肯定会如何右上角那个刺眼的 debug 标志苦恼过。
方法很简单。将 debugShowCheckedModeBanner
参数设置为 false
即可。
MaterialApp(
debugShowCheckedModeBanner: false
)
Flutter 提供性能测试/调试参数,这些参数通常是布尔类型,只要在代码中打开相应的参数就可以开始进行性能测试。
saveLayer
,详情请参考 Checking for offscreen layersMaterialApp(
checkerboardOffscreenLayers: true,
checkerboardRasterCacheImages: true,
)
Flutter framework 的每一层都提供了函数来输出当前状态或事件到控制台(这些函数调用 debugPrint
)。
调用 debugDumpApp() 输出 the state of the Widgets library。不应在 build()
方法中调用 debugDumpApp()
,可以在调用 runApp()
后的任何时候调用 debugDumpApp()
。调用 debugFillProperties() 方法向 debugDumpApp()
的输出添加自定义信息。
调用 debugDumpRenderTree() 方法来输出 rendering tree,用于分析布局问题。建议在 frame callback 或 event handler 中调用 debugDumpRenderTree()
方法。分析布局问题时,关注的关键字段是 size
和 constraints
。调用 debugFillProperties() 方法向 debugDumpRenderTree()
的输出添加自定义信息。
调用 debugDumpLayerTree() 方法来输出 layer tree,用于分析 compositing 问题。
The RepaintBoundary widget, which creates a RenderRepaintBoundary in the render tree, creates a new layer in the layer tree. This is used to reduce how much needs to be repainted.
可以使用 RepaintBoundary
来在 render tree 中创建 RenderRepaintBoundary
,即,在 layer tree 中创建新的 layer。这种方法可以减少重绘工作。详细可参考 说说Flutter中的RepaintBoundary - 掘金。
调用 debugDumpSemanticsTree() 方法来输出 semantics tree (这棵树表示 system accessibility APIs)。暂时用不上,略过。
调用 debugPrintBeginFrameBanner 和 debugPrintEndFrameBanner 方法来输出一帧的开始和结束。
void main() {
runApp(DemoApp());
debugPrintBeginFrameBanner = true;
debugPrintEndFrameBanner = true;
}
debugPaintSizeEnabled 用于调试布局问题。其用法如下:
void main() {
debugPaintSizeEnabled = true;
runApp(DemoApp());
}
Padding
等控件 (带一个深蓝色 box)Center
和 Align
等控件,以黄色箭头显示Container
就属于这一类debugPaintBaselinesEnabled 的作用类似,它显示的是对象的基线。
debugPaintPointersEnabled 用于开启一个特殊的模式:该模式下被点击的对象以蓝绿色显示。这个功能用于检查 hit test 是否正确。
还有几个用于调试 compositor layer 的 flag,
RepaintBoundary
控件RepaintBoundary
注意:所有这些以 debug 开头的 flag 均只能工作于 debug 模式。
调试动画的最有效方式是减慢其速度。可以使用 DevTool 中 Inspector view 的 Slow Animations 按钮来减慢。可以使用 timeDilation 来更精确地控制动画速度。
debugPrintMarkNeedsLayoutStacks - 如果 layout 次数比预期中的要多,可以通过这个 flag 来观察 render box 被置为 dirty 的原因。
TODO
checkerboardOffscreenLayers
)checkerboardRasterCacheImages
)优化点:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。