iOS 性能优化:使用 MetricKit 2.0 收集数据

作者:Jerry4me,iOS 开发者,目前就职于字节跳动抖音直播团

来源丨老司机技术周报(ID:LSJCoding)

Sessions: https://developer.apple.com/videos/play/wwdc2020/10081/

概览

MetricKit 是苹果 iOS13 推出的框架,他会在一天结束后,将过去 24 小时内收集的性能数据归集在一起,并在下一次 App 启动时,通过 delegate 方法回调给我们。

@protocol MXMetricManagerSubscriber <NSObject>
- (void)didReceiveMetricPayloads:(NSArray<MXMetricPayload *> * _Nonnull)payloads;
@end

一个 MXMetricPayload 对象就是一个周期(24 小时)内收集到的所有性能指标的集合。如果有 24 小时以前未被收集过的数据,也会在这里一并返回给我们。所以 delegate 方法这里给到我们的是一个数组。想了解关于 MetricKit 指标的更详细的信息,可阅读 WWDC 2019 Session - 417 Improving Battery Life and Performance[1].

MetricKit 将系统收集的数据交给开发者,让我们自己去决定如何利用这些数据去打造一个更省电、性能更好的 App。

如何集成使用 MetricKit

MetricKit 的接入基本属于无侵入,并且步骤十分简单。

  1. 获取 MXMetricManager 单例

  2. 添加订阅者

  3. 实现 delegate 回调

That's it !

系统是怎么收集 MetricKit 的数据的

系统会在一天你使用 App 的时候被动地获取、汇总 App 的性能数据。而且为了保护用户的隐私,这些数据都是匿名存放的。最终一天结束的时候,系统会将一天内收集到的这些数据打包成一个 MetricKit 的数据包,也就是前面提到的 MXMetricPayload

MXMetricPayload 包含了许多性能指标,如下:

@interface MXMetricPayload : NSObject <NSSecureCoding>

/// 电池指标@property (readonly, strong, nullable) MXCellularConditionMetric *cellularConditionMetrics;@property (readonly, strong, nullable) MXCPUMetric *cpuMetrics;@property (readonly, strong, nullable) MXDisplayMetric *displayMetrics;@property (readonly, strong, nullable) MXGPUMetric *gpuMetrics;@property (readonly, strong, nullable) MXLocationActivityMetric *locationActivityMetrics;@property (readonly, strong, nullable) MXNetworkTransferMetric *networkTransferMetrics;

/// 性能指标@property (readonly, strong, nullable) MXAppExitMetric *applicationExitMetrics; // New for iOS 14@property (readonly, strong, nullable) MXAppRunTimeMetric *applicationTimeMetrics;@property (readonly, strong, nullable) MXMemoryMetric *memoryMetrics;

/// 用户交互相关的响应性指标@property (readonly, strong, nullable) MXAppLaunchMetric *applicationLaunchMetrics;@property (readonly, strong, nullable) MXAnimationMetric *animationMetrics; // New for iOS 14@property (readonly, strong, nullable) MXAppResponsivenessMetric *applicationResponsivenessMetrics;

/// 磁盘存取指标@property (readonly, strong, nullable) MXDiskIOMetric *diskIOMetrics;

/// 自定义指标@property (readonly, strong, nullable) NSArray<MXSignpostMetric *> *signpostMetrics;

@end

系统会将打包的这些数据转化成可读性更高的格式输出给我们,如下图所示:

数据分为三种聚合类型:累积的总和、平均数和分组数据。系统这样处理后,对于我们后续要针对某指标进行的一系列性能优化具备一定的指导意义。例如我们需要把某某指标的总耗时、平均耗时要下降到多少毫秒等等。

MetricKit 1.0 未解决的问题

在某些性能指标方面,光有这些还不足以让我们去定位问题,找到解决问题的方案。

例如 App 的冷启动和热启动的时长数据,我们可以看到数据中冷启的次数远远比热启的次数要多。为了提高用户体验,我们当然是希望热启的次数更多。但是这种情况我们没办法根据这些数据去帮助我们定位和解决问题。

另一个典型的指标是 CPU 时间。我们可以看到 App 在前台的时间要远多于 CPU 时间。单纯根据这份报表我们没办法知道这是否是我们预期内的结果。

不用着急,MetricKit 2.0 给了我们新的指标和 API 帮助我们深入地研究这类问题,进一步明确 App 的工作负荷、性能和稳定性。

MetricKit 2.0

新的性能指标

MetricKit 2.0 新增了三种指标:CPU 指令、滚动卡顿和应用程序退出。

@property (readonly, strong) NSMeasurement<NSUnit *> *cumulativeCPUInstructions; // New for iOS 14

CPU 指令是 MXCPUMetric 新增的一个属性 cumulativeCPUInstructions 表示一个周期内 CPU 执行的指令总数。这个指标是衡量 App 在 CPU 工作负荷的绝对指标,与硬件和频率都没有关系。他能帮助我们更准确地量化 App 的总负荷。

@property (readonly, strong) MXAnimationMetric *animationMetrics; // New for iOS 14

滚动卡顿是 MetricKit 在 iOS 14 上新增的一个指标  MXAnimationMetric。他指的是渲染的帧在滚动过程中的预期时间未出现在屏幕上,也就是我们俗称的掉帧。MetricKit 会为我们提供 App 中滚动卡顿的时间与滚动的时间之比来帮我们了解 App 的滚动性能。

如果想要了解怎么用 XCTest 对这个指标进行衡量,可以观看 WWDC 2020 - 10077 Eliminate animation hitches with XCTest[2].

@property (readonly, strong) MXAppExitMetric *applicationExitMetrics;

应用程序退出是 MetricKit 在 iOS 14 上新增的一个指标 MXAppExitMetric。他统计的是每天应用程序在前台、后台运行的时候退出或被杀的原因概述。

如果想要了解怎么利用这指标,可以观看 WWDC 2020 - 10078 Why is my app getting killed?[3]

新特性 - 诊断

回到数据包这张图的应用程序挂起持续时间的直方图中,我们知道应用程序挂起是用户体验极其差的一种情况,在 MetricKit 1.0 的时候我们没办法去确认根本原因,但在 MetricKit 2.0 中,我们有了新的特性 - 诊断。

诊断功能相关 API

MetricKit 2.0 为我们提供了 4 种诊断类型:应用程序挂起、崩溃、磁盘写入异常和 CPU 异常。

挂起是指应用程序长时间不响应用户输入的情况,可能是主线程繁忙或被阻塞。MetricKit 为我们提供应用程序无响应的持续时间以及主线程的调用栈。

CPU 异常诊断可以在 Xcode Organizer 中查看,诊断信息包含消耗的 CPU 时间、CPU 高使用率期间的总时长和消耗 CPU 时间的线程调用栈。与性能数据(Metric Payload)结合起来对于找出不易复现的回归非常有用。

磁盘写入异常诊断跟 CPU 异常诊断很相似,每个诊断会包含造成异常的写入总数,以及导致过多写入的线程调用栈。并且这些诊断当应用程序超过了每天 1GB 的阈值时就会生成。

崩溃诊断会把每次 App 崩溃的时候将异常信息、崩溃原因、错误访问情况下的虚拟内存信息以及崩溃调用栈给到我们。

如何使用诊断功能

MetricKit 2.0 为我们提供了新的 delegate 回调,让我们可以方便地查看诊断信息。

集成步骤也非常简单,实现 delegate 协议的方法即可。

MetricKit 会在用户使用 App 的时候同步收集诊断信息,然后每天结束的时候将他们打包成 MXDiagnosticPayload 给到我们。这样我们就拥有了同一个时间段的性能数据和诊断数据。

由于他们是一一对应的,所以我们在对性能数据产生疑问的时候就可以掏出对应的诊断数据来进行排查。由于有了这些一一的对应关系,所以 MetricKit 2.0 也随之来了一些新的基类:

  • MXDiagnostic :所有诊断类集成的基类

  • MXDiagnosticPayload :诊断包,包含一天结束时的所有诊断

  • MXCallStackTree :新数据类,用于封装当前环境的调用栈

MXCallStackTree 封装的调用栈并没有经过符号化,旨在用于设备外处理,非 debug 用。转换成 JSON 后如下所示:

如果想要了解怎么利用这些调用栈数据,可以观看 WWDC 2020 - 10057 Identify trends with the Power and Performance API[4].

总结

总的来说,MetricKit 2.0 填了 1.0 版本的一些坑,为我们提供了更多强大的 API 以及配套的工具,帮助我们去分析和解决一些疑难杂症。只要把 Metric Payload 与 Diagnostic Payload 结合起来,双剑合璧,对我们去定位线上的一些难以复现、毫无头绪的问题有很大的帮助。

[1]

WWDC 2019 Session - 417 Improving Battery Life and Performance: https://developer.apple.com/videos/play/wwdc2019/417/

[2]

WWDC 2020 - 10077 Eliminate animation hitches with XCTest: https://developer.apple.com/videos/play/wwdc2020/10077

[3]

WWDC 2020 - 10078 Why is my app getting killed?: https://developer.apple.com/videos/play/wwdc2020/10078

[4]

WWDC 2020 - 10057 Identify trends with the Power and Performance API: https://developer.apple.com/videos/play/wwdc2020/10057

程序员专栏
(0)

相关推荐

  • 惊艳!iOS 15 巨量更新,Mac 与 iPad 无缝融合,苹果竟与鸿蒙殊途同归

    在不动声色的更新背后,苹果是在下一盘大旗. " 作者|李帅飞 肖漫 在鸿蒙 OS 2.0 发布 5 天后,苹果也出手了. 美国太平洋时间 2021 年 6 月 7 日,又是一年 WWDC,苹 ...

  • 苹果刚刚发布的iOS 15,越来越像安卓

    WWDC发布之日,小雷秃头之时... 没错,苹果一年一度的WWDC(全球开发者大会)将于今晚凌晨一点举行. 对于各位科技极客来说无疑是一件激动人心的事儿. 但对于发际线早已接近贝克汉姆的小雷来说,喜忧 ...

  • 干货:C 的性能优化

    前言 性能优化不管是从方法论还是从实践上都有很多东西,从 C++ 语言本身入手,介绍一些性能优化的方法,希望能做到简洁实用. 实例1 在开始本文的内容之前,让我们看段小程序: // 获取一个整数对应1 ...

  • 昌平区开展“优化营商环境4.0版改革政策”企业专场培训

    日前,昌平区开展"优化营商环境4.0版改革政策"企业专场培训,广泛深入宣传北京市优化营商环境改革新成效.新亮点,帮助企业知晓和准确理解把握优化营商环境4.0版改革政策,提升企业社保 ...

  • 天津滨海新区出台优化营商环境4.0版方案

    中国经济导报讯  记者王敏报道  日前,<滨海新区打造国际一流营商环境实现高质量发展2021行动计划>正式发布,标志着天津市滨海新区优化营商环境改革再进一步.     据介绍,近年来天津滨 ...

  • Android 性能优化必知必会 · Android Performance

    做了这么久性能相关的工作,也接触了不少模块,说实话要做好性能这一块,真心不容易.为什么这么说? 是因为需要接触的知识实在是太多了, Android 是一个整体,牵一发而动全身,不是说只懂一个模块就可以 ...

  • 浅谈面向客户端的性能优化

    有朋友通过<智能音箱场景下的性能优化>一文找到了我,既然智能音箱的性能优化相当于一个超集,那么对其的一个子集--客户端系统如何进行性能优化呢? 反正隔离在家,不妨对客户端的性能优化梳理一下 ...

  • 智能音箱场景下的性能优化

    QCon是由InfoQ主办的综合性技术盛会,今年是Qcon举办的第10个年头,半吊子全栈工匠有幸作为演讲嘉宾分享一个近两年来的实践经验--智能音箱场景下的性能优化,隶属于曾波老师出品的"场景 ...

  • 如何配置Nginx压缩实现性能优化?怎么学Linux系统

    如何配置Nginx gzip压缩实现性能优化?是每个Linux运维管理人员都需要掌握的技能.互联网时代发展迅速,Linux运维技术的需求更多推进不少.市场对于Linux运维人才的需求也在逐渐加大.Li ...

  • Flutter 2.2发布:针对各平台的性能优化、完善生态支持

    局长 OSC开源社区 昨天 文 | 局长 出品 | OSC开源社区(ID:oschina2013) 谷歌在昨日举办的 Google I/O 2021 大会上宣布了 Flutter 2.2,其开发团队称 ...

  • Web性能优化之图片延迟加载

    来源:微信公众号CodeL 对于一些图片多,页面长的网页来说,如果每次打开页面加载全部的网页内容,页面加载速度势必会受到影响,如果每次打开网页只将网页可视区域的内容加载给用户 ,将大大提高网页浏览速度 ...