移动应用的启动时间,是 App 性能的重要衡量指标。启动时间的快慢会直接影响用户对一款应用的判断和使用体验。知乎 iOS App 包含非常多且复杂度高的业务模块(如视频等),也接入了很多第三方的组件,随着业务需求的迭代,线上数据监控反映出来我们的启动时间越来越慢。而启动时间的快慢,本身是一个比较主观的感受。因此,除了知乎 App 自己的启动时间数据,还需要对启动时间进行竞品的横向测试。我们会在这篇文章中介绍知乎测试团队针对 iOS 竞品启动时间测试的一些实践,并结合工程师启动时间优化的结果,介绍持续监控启动时间、主动发现启动异常的测试方案。
常见的启动时间测试方法介绍及对比
常见的 iOS 启动时长测试方法,主要有以下几种
Xcode Developer Tool: 使用 Instruments 的 Time Profiler 插件,可以检测 App CPU 的使用情况。能看到 App 的启动时间和各个方法消耗的时间;
客户端计算统计: 通过 hook 关键函数的调用,计算获得性能数据。目前知乎 App 性能监控已有启动时长数据,类似的还有一些第三方的性能测试工具;
录屏:使用截屏、录屏、高速摄像机录像等方法,记录移动设备屏幕上的变化,分析启动的起止点,获取 app 启动的耗时。
方法 1 可以精确获取各个方法调用的耗时,需要 App 是 developer 证书签名,否则无法执行测试;方法 2 可以精确获取各个启动项耗时,但和实际用户体验感受有一定出入,且需要拿到客户端源码,将工具嵌入客户端中;方法 3 和用户直观感受一致,但分析截屏、视频较麻烦,且发现问题时,无法定位到具体的启动耗时项。目前对于竞品启动时长的对比测试,由于源码和签名的限制,方法 1 和 2 都不太合适。
录屏测试方案需要解决的问题
录屏测试方案通过记录移动设备屏幕的变化,分析用户从点击 App 图标到看到主体框架出现的时长,因此启动时长的判断必然会受到开屏广告的影响。而各 App 在展示开屏广告的过程中,可能会有其他启动项在执行。因此去掉开屏广告的启动时长测试,会更有参考价值。在我们反复尝试各 App 后,总结出以下两个不展示开屏广告的规律。
开屏广告一般的逻辑是拉取到素材后,下一次启动开屏展示。可以尝试清理 App 缓存后,再启动 App;
部分 App 一天内多次启动后,不会再展示开屏广告
测试方案制定
启动场景制定
在 2016 年的 WWDC 《Optimizing App Startup Time》议题上,提到了启动分为冷启动和暖启动两种。暖启动是指内存中包含 App 的相关数据,与我们日常提到的热启动不太一样,连续杀掉 App 的启动也可能是暖启动。冷启动是指系统的内核缓存区里没有 App 相关数据。冷暖启动的启动时间会差异比较大,冷启动的数据更能反映 App 真实的启动时长。保证 App 是冷启动的方法,就是通过重启设备,清理系统内核缓存区。
Optimizing App Startup Time - Slide Page 126
因此我们的测试方案,需要分为冷启动和暖启动两组场景,冷启动提供更真实的启动时长数据,暖启动数据反映用户日常使用的体验感受(毕竟苹果用户不会经常重启设备)。
录屏工具及视频分析
录屏工具我们选取了开源的工具 xrecord。设备连接上电脑后,通过 xrecord 工具将视频文件录制到本地。在每个设备每个 app 启动测试一次,产生视频一条。
视频内容包含:桌面 → 被测 App 图标变黑 → 展示知乎开屏 → 展示主体框架 → 首页内容加载完成。由于首页内容加载完成是异步实现的,因此我们选取分析的关键节点,是「被测 App 图标变黑」和「展示主体框架」这两个点。通过 FFmpeg 将视频转换成分帧后的图像,剔除相似度较高的图像后,再进行人工选取关键节点。
竞品选择
竞品的选择需要综合考虑包体积、业务复杂度、业务类型等因素,选择和知乎体量相当的 App 进行真实的同等机型测试。否则相差较大的应用,启动时间的参考意义也不大。
优化前结果
经过实际测试后,我们发现:
知乎在同类竞品中,冷暖启动的启动时长都处于较慢水平
大部分 App 的暖启动时长,比冷启动时长快非常多(极个别 App 是冷启动比暖启动快,如竞品 C)
详细测试结果如下:
优化后结果
在知乎移动平台 iOS 工程师的不懈努力下,经历多个版本的迭代优化,最终知乎 iOS App 的启动时长终于在同类竞品中处于较快水平,优化效果非常明显,
详细测试结果如下:
如何「守住」优化后的结果
业务的快速发展不可避免的会导致启动时间逐步增长,如何「守住」工程师们辛苦「攻下」的优化成果呢?录屏分帧测试虽然结果非常有说服力,但每个版本测试包含录制、标注、整理报告等环节,且需要对同一个机型进行多组测试来减少误差,需要耗费约 3 人/天的工作量。如果每个版本都进行一次测试,将会耗费大量测试人力。且这种测试方法只能给出整体启动时长的报告,无法准确定位到启动的异常。因此我们尝试做了一些低成本、能快速反馈的自动化测试。
目前,知乎 iOS App 启动项分为三种:
同步 - App 启动后在主线程立即执行
异步 - App 启动后主线程队列执行完毕后,立即创建异步线程执行
延迟 - App 启动后主线程队列执行完毕后,延迟一段时间在主线程执行
同步启动项是决定启动时长的关键因素,知乎移动平台 iOS 工程师团队在知乎自研的性能收集 APM SDK 中,加入了同步启动项的耗时收集,并记录在沙盒的数据库中。通过这些数据,我们可以轻松的分析每次启动时的耗时情况。
知乎的代码是托管在 Gitlab 上,每一个需求的提测,都是对应到一个 Merge Request。我们希望针对 Merge Request 进行测试,确认代码变动不会引入增加启动耗时的风险,才能正常合入。 在 Merge Request 打出包后,通过 ios-deploy 工具,在真机上自动安装知乎 App 并启动 10 次。测试结束后,客户端上报记录的启动时长数据到数据收集服务。数据收集服务进行汇总分析,并用前端图表给出直观的展示。整体测试在 Jenkins Pipeline 里完成,测试流程如下:
测试流程图
测试报告主要提供平均启动时长、启动项数量、各个启动项占用的时长等几个维度,通过图表展示,非常直观的看到各个启动项的时间占用。
对于新增启动项或启动时长远超过平均值时,会给出对应的警告反馈,需要 Merge Request 的负责人跟进排查。
测试报告列表
测试报告详细数据
通过这套自动化测试方案,能够快速的找到新增启动项和启动明显变慢的 Merge Request,更有效的帮助我们「守住」优化后的成果。
未来的规划
启动速度优化是一个持续的工作,「攻」和「守」双方面都要关注。除了分析 APM SDK 记录的启动项时间,我们也不会放弃录屏分帧的测试方法,毕竟它是最直观的用户感受。后续我们也会尝试使用机器学习领域的技术对图像进行识别,训练原来人工标注的视频帧,自动识别出新录制视频里的启动开始和结束的那两帧,提高录屏测试方法的标注效率。
评论