Flutter Engine 调优系列 (一) – Flutter 页面打开速度优化
在给 flutter engine 进行调优定制过程当中,我们针对 flutter 进行了一系列的改良,也拓展了一些原有的基础建设(包括 flutter apm 体系, flutter monkey 测试 等),这篇文章将会介绍一下 flutter 页面打开速度优化 的调研过程和方案,并且由此开发的 线上 trace系统 也希望能给后续类似需求提供一些经验和方向。
打开速度埋点
- 起始时间
点击 flutter 页面的入口按钮
- 结束时间
gpu 第一帧渲染完成
未优化之前的线上数据
机型 | 90 分位耗时 (毫秒) |
---|---|
iPhone 6 Plus | 2510 |
线上数据非常出乎意料,iPhone 6 Plus 的表现竟然如此糟糕,90 分位耗时达到 2510 毫秒,这个指标需要得到改善,针对这个问题我们开始展开调研。
线下调研
我们找来一台 iPhone 6 Plus 设备,手动测试过程当中观察了一下埋点数据,发现数据并没有 2510 毫秒那么差,线下测试 100 - 500 毫秒的数据都有出现过,我们接着再细分了一些线上数据的分布,得到结果如下:
机型 | 0 -> 500 毫秒 | 500 -> 1000 毫秒 | 1000 -> 2000 毫秒 | > 2000 毫秒 |
---|---|---|---|---|
iPhone 6 Plus | 48.9 % | 15.1 % | 15.3 % | 20.7 % |
看来只凭开发在本地测试有可能找不到线上用户真正发生的瓶颈,我们需要一种手段去了解线上用户在打开 flutter 页面过程当中耗时瓶颈是什么。
线上策略
我们希望能够精准的定位耗时瓶颈,所以需要实现一套类似于 xcode instruments time profiler 的功能,但是 xcode instruments time profiler 还不是很直观,其实 android 的 trace view 功能是我们想要的功能,能够直观的分析整个运行过程的调用时序,以及耗时过长的函数,所以 trace view 也常常用于卡顿,启动分析等场景,为此,我们开发了 ios 版的 线上 trace 功能。
最终的 trace view 效果如下图所示:
ios trace 实现原理
- 客户端堆栈聚合上报
当 trace 功能开启的时候会激活采样线程,采样线程以 100 毫秒的频率去捕获所有的线程堆栈,trace 功能关闭的时候会将之前的堆栈进行聚合上报,采样聚合过程如下:
第一次采样的调用链
A -> B -> C
第二次采样的调用链
A -> B -> D
合并后的调用链
A (2) -> B (2) -> C(1), D(1)
有了整个调用链的层级、以及频率信息之后,则可以生成 trace view 树进行展示。
- 服务器聚类 && 生成 trace view 树
根据客户端上报的调用链信息,从中提取频率 > 50% 的栈顶函数作为聚类信息,这样可以将类似的调用链聚合在一起。
比如: A (2) -> B (2) -> C(1), D(1) 这个调用链就可以提取 B (2) 作为聚类信息。
分析线上 trace view
我们针对 点击 flutter 页面入口按钮 到 gpu 第一帧渲染完成 这一过程开启了 trace 的功能,并且对这一过程 > 2000 毫秒的数据进行上报,经过服务器聚类之后,大部分 trace view 瓶颈如下图所示:
进入 flutter 页面的时候会进行 engine 的创建,flutter::shell::create 会等待 flutter ui 线程将 dart vm 以及 dart isolate 创建完成,而瓶颈点是在创建 dart isolate 这一过程当中,flutter::DartIsolate::CreateRootIsolate 的执行耗时高达 1300 毫秒,这一步的发现为后续提供优化方案 提供了非常重要的方向和线索 。
dart isolate 的创建涉及到大量的 io 操作,即使是同一款机型,在不同的运行状态下也会有不同的表现,所以线上的数据会有呈现出一种分布,在线下测试过程当中也不容易复现,我们决定将 dart isolate 放在异步线程当中进行预加载,这种方案不需要初始化 engine 的其他部分,比如:opengl相关的视图缓存,内存占用会更少,并且可以进行异步化避免卡顿 (官方 engine 本身是只能在主线程进行初始化的)。
优化方案效果
机型 | 90 分位耗时 (毫秒) |
---|---|
iPhone 6 Plus | 1169 |
更多
这套 trace 系统能够方便的获取线上 app 的运行状态,给优化工作提供了具有极大意义的参考,在线下自动化测试我们也提供了更高精度,更强大的 trace 功能,用于启动耗时分析,页面打开分析,以及 逆向系统库和第三方应用 等多个领域,希望能给大家带来这方面的参考。