Flutter应用如何调试–DevTools介绍(上)
Flutter应用如何调试–DevTools介绍(中)
Flutter应用如何调试–DevTools介绍(下)
Dart DevTools主要有7个工具,其中Flutter inspector
与Debugger
只能在debug模式下查看,Timeline、Memory、Performance
更倾向于在Profile模式下使用,Network、Logging
则无模式要求,下面将对它们进行详细介绍,如有疏漏或者错误,欢迎与我联系交流。
- Flutter inspector
- Timeline
- Memory
- Performance
- Debugger
- Network
- Logging
1、Flutter inspector工具
简介:inspector是用于可视化和浏览Flutter小部件树的强大工具,用来可视化和浏览Flutter widget trees,以便:
- 了解现有布局
-
诊断布局问题
Flutter inspector运行在debug模式下。
除了在网页上查看,Flutter inspector还可以在Android Studio的右侧区域进行插查看
两者本质上没有太大区别,IDE中多了一个查看Render Tree
的入口,网页上则可以对布局进行调试,并且视图窗口更大,除此之外没有太大区别。
Select Widget Mode
我们开发Flutter应用,知道Widget的设计理念是组合大于继承,一层层的Widget嵌套,使得排查Flutter widget trees的时候,也往往受制于嵌套,有了inspector工具可以使得我们一步即可找到widget trees的对应节点。勾选中途中红色的第一个控件Select Widget Mode
,我们可以再手机屏幕上选中想要查看的组件,或者选中widget trees中的节点,然后就是令人激动的功能:手机屏幕中、代码中、DevTools中,相应的地方也都会自动同步
,方便我们定位问题,在Detail Tree
中我们还可以看到选中widget的详细属性。
另一个令人激动的点是,我们可以不用修改代码就可以对布局进行调整,这就是动态调试
Layout Explorer
,可以改变主轴方向,flex权重等属性。Slow Animation
当我们调试动画的时候,会希望动画慢点播放,就像iOS模拟器支持的Slow Animation
一样,inspector工具的Slow Animation
也支持将动画速度放慢5倍,如过希望自定义的话可以通过编码的方式,设置timeDilation属性,最多支持1到50倍慢放。
其它选项
-
Refresh Tree
可以刷新当前widget信息 -
Debug Paint
在页面上添加一些调试样式,以显示边框,填充,对齐和间隔,如下图 -
Paint Baselines
则会使每个RenderBox在其每个文本基线处绘制一条线。 -
Repaint Rainbow
重绘时在图层上显示旋转颜色。 -
Debug Banner
即使运行调试版本,也可以切换调试标语的显示。
2、Timeline工具
Timeline需要在profile模式下运行,否则不能准确地统计APP真是的性能。
首先对上面四个按钮进行介绍:
Refesh
,滑动手机APP,然后点击refresh,则会在下方显示刚才一段时间内的帧图(图中柱状部分)和火焰图(图中中间区域)。
Profile granularity
也叫分析粒度,默认样本室250微妙采样一次,即medium,采样率低中高分别对应抽样率低、中、高粒度分别顺序对应 1/50μs、1/250μs 和 1/1000μs,正确的设置此粒度对性能分析非常总要,高粒度 的配置会具有更高的采样率,采集信息更多,甚至于VM被中断以收集采集样本,导致性能下降。
Performance Overlay
即性能图层,选中之后会在APP上显示两张图标显示性能信息
如图所示,最顶部的图形表示 raster 线程所花费的时间,底部的图表显示了 UI 线程所花费的时间。纵轴表示每一帧花费时间,而横轴则表示帧。只有当你的应用绘制时这个图表才会更新,所以如果它空闲的话,图表就不会动。图中的绿色竖条表示当前帧,为绿色表示性能良好,为红色则表示出现了卡顿,如果是在 UI 图表出现了红色竖条,则表明 Dart 代码消耗了大量资源。而如果红色竖条是在 GPU 图表出现的,意味着场景太复杂导致无法快速渲染。
Flutter线程
这里对Flutter的线程做简单说明,Flutter使用多个线程来完成其工作,尽管覆盖图中仅显示了两个线程。您所有的Dart代码都在UI线程上运行。尽管您没有直接访问任何其他线程的权限,但是您对UI线程的操作会对其他线程产生性能影响。
-
Platform thread
也叫平台线程,plugin的代码将会运行在这里,对应Android和iOS的主线程MainThread
-
UI thread
UI 线程在 Dart VM 中执行 Dart 代码。该线程包括开发者写下的代码和 Flutter 框架根据应用行为生成的代码。当应用创建和展示场景的时候,UI 线程首先建立一个 图层树(layer tree) ,一个包含设备无关的渲染命令的轻量对象,并将图层树发送到 GPU 线程来渲染到设备上。 不要阻塞这个线程! 在性能图层的最低栏展示该线程。 -
Raster thread
(以前叫 GPU 线程),中文名字叫光栅线程或者栅格线程,raster 线程拿到 layer tree,并将它交给 GPU(图形处理单元)。你无法直接与 GPU 线程或其数据通信,但如果该线程变慢,一定是开发者 Dart 代码中的某处导致的。图形库 Skia 在该线程运行,并在性能图层的最顶栏显示该线程。这个线程之前被叫做 “GPU 线程”,因为它为 GPU 进行栅格化,但我们重新将它命名为 “raster 线程”,这是因为许多开发者错误的(但是能理解)认为该线程运行在 GPU 单元。 -
I/O thread
执行昂贵的操作(常见的有 I/O)以避免阻塞 UI 或者 raster 线程。这个线程将不会显示在 performance overlay 上。
除此之外我们分析Flutter APP的时候,应该在真机上,并且最好用性能较差的机型去多次分析。在分析性能的时候,不应只局限于当前设备运行流畅。
- 将帧渲染时间降低到 16ms 以下可能在视觉上看不出来什么变化,但可以延长电池寿命以及避免发热问题。
- 可能在你当前测试设备上运行良好,但请考虑在应用所支持的最低端设备上的情况。
- 当 120fps 的设备普及之后,便需要在 8ms 之内完成每一帧的渲染来保证流畅平滑的体验。
好了基本概念介绍完了,我们继续介绍Timeline的使用
帧图
中的每一个竖条都是可以点击的,点击周后,下面的火焰图
相应的帧也会随之选中,在火焰图中我们可以分析UI线程和Raster线程
,可以对其进行单指上下左右滑动,也可以双指进行放大缩小。
Track Widget Builds
,Timeline
中的最后一个按钮,这个按钮选中的时候,可以在火焰图中的UI帧中
看到具体是用户写的哪一个widget,如果这个widget占用时间过多的话,我们就可以针对行的进行优化,如上面的图中所示KnowlwdgeCellWidget
的创建花了4.5ms,点击选中它,在视图的地步还会显示CPU Flame Chart
、Call Tree
、Bottom Up
这里先不做介绍,会在Performance
进行讲述。
Memory
内存分析可以帮助我们查看在某一时刻内存使用情况,能够具体到某个类使用了多少内存,主动触发垃圾回收等。
默认进来的时候只有图中蓝色的区域,点击
Android Menory
也会显示,当鼠标点击图标的时,会显示一个浮动窗口,显示内存使用具体数值。
Snapshot
单击Snapshot
按钮,会显示当前内存对象表。可以按类名称,大小,分配的实例等对内存对象进行排序。还可以点击右侧进行搜索。
如图中,选中了d_stack进行分析,右侧是d_stack框架中Flutter侧的,DStack类占用的内存,甚至可以看到内存中存储了哪些数据。
我们可以在Search
直接搜索想要查看的类,方便快速查找。
除了看数据列表,我们还可以以堆栈视图的方式查看内存分布,当我们选中Heat Map
开关的时候,下面会呈现内存视图,下面区域是上面的总和,鼠标放在某一个块中,当前块会展开为更细粒度的使用情况,如下图
也可以对堆栈信息进行搜索,方便快速查看
受限于篇幅,本篇就介绍到这里,剩下的
- Performance
- Debugger
- Network
- Logging
留到Flutter应用如何调试--DevTools介绍(下)介绍。