抖音品质建设 - iOS启动优化《实战篇》

对应着本文的三大模块:监控工具最佳实践。

监控

==

启动埋点


既然要监控,那么就要能够在代码里获取到启动时长。启动的起点大家采用的方案都一样:进程创建的时间。

启动的终点对应用户感知到的 Launch Image 消失的第一帧,抖音采用的方案如下:

  • iOS 12 及以下:root viewController 的 viewDidAppear

  • iOS 13+:applicationDidBecomeActive

Apple 官方的统计方式是第一个 CA::Transaction::commit,但对应的实现在系统框架内部,抖音的方式已经非常接近这个点了。

分阶段


只有一个启动耗时的埋点在排查线上问题的时候显然是不够的,可以通过分阶段和单点埋****点结合,下面是这是目前抖音的监控方案:

+load、initializer 的调用顺序和链接顺序有关,链接顺序默认按照 CocoaPod 的 Pod 命名升序排列,所以取一个命名为 AAA 开头既可以让某个 +load、initializer 第一个被执行。

无侵入监控


公司的 APM 团队提供了一种无侵入的启动监控方案,方案将启动流程拆分成几个粒度比较粗的与业务无关的阶段:进程创建,最早的 +load,didFinishLuanching 开始和首屏首次绘制完成。

前三个时间点无侵入获取较为简单

  • 进程创建:通过 sysctl 系统调用拿到进程创建的时间戳

  • 最早的 +load:和上面的分阶段监控一样,通过 AAA 为前缀命名 Pod,让 +load 第一个被执行

  • didFinishLaunching:监控 SDK 初始化一般在启动的很早期,用监控 SDK 的初始化时间作为 didFinishLaunching 的时间

首屏渲染完成时间我们希望和 MetricKit 对齐,即获取到 CA::Transaction::commit()方法被调用的时间。

通过 Runloop 源码分析和线下调试,我们发现 CA::Transaction::commit()CFRunLoopPerformBlockkCFRunLoopBeforeTimers 这三个时机的顺序从早到晚依次是:

可以通过在 didFinishLaunch 中向 Runloop 注册 block 或者 BeforeTimer 的 Observer 来获取上图中两个时间点的回调,代码如下:

//注册block

CFRunLoopRef mainRunloop = [[NSRunLoop mainRunLoop] getCFRunLoop];

CFRunLoopPerformBlock(mainRunloop,NSDefaultRunLoopMode,^(){

NSTimeInterval stamp = [[NSDate date] timeIntervalSince1970];

NSLog(@“runloop block launch end:%f”,stamp);

});

//注册kCFRunLoopBeforeTimers回调

CFRunLoopRef mainRunloop = [[NSRunLoop mainRunLoop] getCFRunLoop];

CFRunLoopActivity activities = kCFRunLoopAllActivities;

CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, activities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {

if (activity == kCFRunLoopBeforeTimers) {

NSTimeInterval stamp = [[NSDate date] timeIntervalSince1970];

NSLog(@“runloop beforetimers launch end:%f”,stamp);

CFRunLoopRemoveObserver(mainRunloop, observer, kCFRunLoopCommonModes);

}

});

CFRunLoopAddObserver(mainRunloop, observer, kCFRunLoopCommonModes);

经过实测,我们最后选择的无侵入获取首屏渲染方案是:

  1. iOS13(含)以上的系统采用 runloop 中注册一个 kCFRunLoopBeforeTimers 的回调获取到的 App 首屏渲染完成的时机更准确。

  2. iOS13 以下的系统采用 CFRunLoopPerformBlock 方法注入 block 获取到的 App 首屏渲染完成的时机更准确。

监控周期


App 的生命周期可以分为三个阶段:研发,灰度和线上,不同阶段监控的目的和方式都不一样。

研发阶段

研发阶段的监控主要目的是防止劣化,对应着会有线下的自动化监控,通过实际的启动性能测试来尽早地发现和解决问题,抖音的线下自动化监控流程图如下:

由定时任务触发,先 release 模式下打包,接着跑一次自动化测试,测试完毕后会上报测试结果,方便通过看板来跟踪整体的变化趋势。

如果发现有劣化,会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值