但是随着业务快速迭代,开发者往往会疏忽大意,写出低性能的代码。理想情况是,通过性能分析工具自动定位到问题代码,及时修改。Flutter官方提供了Devtools性能分析工具,它的timeline界面可以逐帧分析应用的UI性能,cpu profiler界面来抓取卡顿过程中的耗时操作。在研发阶段,我们可以使用这个工具来分析本地可以复现的卡顿问题。但是,Devtools的局限性在于:
-
只能用于在出现卡顿问题后去分析,无法做到监控卡顿问题。
-
只能用于线下排查,对于线上反馈卡顿问题,因为没有足够的场景,也无能为力。
为此我们需要建设一个Flutter卡顿工具,用于在线上线下监控定位造成卡顿的耗时函数。实现思路:我们知道release模式下的Dart代码是基于AOT编译的,业务代码和sdk都会编译成平台相关的机器码,所以我们是可以通过信号机制抓取native的堆栈,再通过符号化还原的方式来获取flutter堆栈。
我们通过卡顿工具定位排查出两类造成流畅度低的问题:耗时函数和过度渲染问题。
定位耗时函数
对于耗时函数导致的卡顿问题,可以通过查看堆栈定位到耗时函数。
从调用栈可以看出channel的调用时数据序列化 和 反序列化比较耗时。通过查看FxImage的代码,了解到resumeImage对应的native实现已经为空,flutter侧其实可以省去这一次channel调用。
定位过度渲染
在自动化阶段上报的数据有大量是如下所示渲染阶段的堆栈,无法定位到业务代码。
这是由于Flutter的刷新机制是中心化、异步的渲染机制, 业务层需要刷新界面元素,framework层会先把需要更新的元素标脏,然后等下一次引擎侧的渲染回调,在这次渲染回调中,对之前收集到的脏元素统一做更新。这样的机制导致在抓取渲染阶段的堆栈有大量的Elem