MetricKit框架详细解析(七) —— Reducing Your App's Launch Time(一)

版本记录

版本号 时间
V1.0 2021.05.14 星期五

前言

MetricKit由iOS13系统进引入,用来汇总和分析有关异常和崩溃诊断以及电源和性能指标的每个设备的报告。下面我们就一起来看下这个框架。感兴趣的可以看下面几篇文章。
1. MetricKit框架详细解析(一) —— 基本概览(一)
2. MetricKit框架详细解析(二) —— Improving Your App's Performance(一)
3. MetricKit框架详细解析(三) —— Reducing Your App's Memory Use(一)
4. MetricKit框架详细解析(四) —— Gathering Information About Memory Use(一)
5. MetricKit框架详细解析(五) —— Making Changes to Reduce Memory Use(一)
6. MetricKit框架详细解析(六) —— Preventing Memory-Use Regressions & Responding to Low-Memory Warnings(一)

Overview

通过最大程度地减少启动时间,为您的应用程序创建更快响应的体验。

用户首次使用应用程序时会等待其启动。启动屏幕向用户显示该应用程序正在准备使用,但也应准备就绪,可以帮助用户尽快完成任务。启动时间太长的应用可能会使用户感到沮丧,并且如果响应时间太长,iOS看门狗进程甚至可能终止它。如果应用是常规工作流程的一部分,则用户一天可能会启动多次该应用,而且启动时间过长会导致用户等待执行任务的时间有所延迟。

当用户在主屏幕上点击某个应用程序的图标时,iOS会在将控制权移交给该应用程序流程之前为该应用程序做好启动准备。然后,该应用程序运行代码以准备将其UI绘制到屏幕上。即使在显示应用程序的用户界面之后,该应用程序仍可能仍在准备内容或用最终控件替换插页式界面(例如,加载微调器)。这些步骤中的每一个都会影响应用程序的总启动时间,您可以采取一些步骤来缩短其持续时间。


Gather Metrics About Your App’s Launch Time

Launch Time pane中或使用MetricKit查看应用程序的启动时间指标。

使用Xcode中的Launch Time pane可查看用户点击图标以启动应用程序到系统绘制启动屏幕以外的时间之间的毫秒数。 使用过滤器检查不同设备上的启动时间,以及典型时间(第50个百分位数)和最长时间(第90个百分位数)。 通过单击图表中所需的release版上的栏,将当前release版的发布时间与先前release版的发布时间进行比较。

除了启动时间外,MetricKit还报告恢复应用程序的时间。


Profile Your App's Launch Time

使用App Launch templateInstruments中为您的应用进行调试。 Instruments会在您的应用程序运行五秒钟,在此期间,它会收集时间配置文件(time profile)和线程状态跟踪。 使用时间配置文件来识别您的应用在启动过程中正在运行的代码。 使用线程状态跟踪来查找线程活动或被阻塞的时间,并发现线程被阻塞的原因。

剖析应用在不同情况下的启动时间,以了解这些因素如何影响体验。 以下是一些要测试的不同情况的示例:

  • 打开设备,首次解锁,然后启动您的应用程序。
  • 强制退出您的应用程序,然后启动它。
  • 打开其他应用程序,然后启动您的应用程序。
  • 使用非常大的应用程序(例如,可以使用许多图形资源或实时摄像机输入的应用程序),然后启动您的应用程序。

UIKit在主线程上绘制视图并处理用户事件,因此在应用程序启动完成后,该线程必须可用于绘制第一帧。 在Instruments线程跟踪中,主线程花费在运行或抢占上的时间是其无法绘制视图或响应用户输入事件的时间。

对于不同的应用启动视图,请使用Time Profile template板对应用进行分析。 App Life Cycle时间轴将应用程序启动期间的活动分为process initialization, UIKit initialization, UIKit initial scene renderinginitial frame rendering


Identify Launch-Time Factors: Dynamic Library Loading

dynamic loader (dyld)加载应用程序的可执行文件,并检查可执行文件中的Mach加载命令,以查找应用程序所需的框架和动态库。 然后,它将每个框架加载到内存中,并解析可执行文件中的动态符号,以指向动态库中的适当地址。

应用程序加载的每个其他框架都会增加启动时间。 尽管dyld在用户安装应用程序时将大量此类工作缓存在启动闭包中,但是启动闭包的大小以及加载后的工作量仍取决于所加载库的数量和大小。 您可以通过限制嵌入的框架数量来减少应用程序的启动时间。 您在Xcode的Target editor中导入或添加到应用的“Linked Frameworks and Libraries”设置中的框架将计入该数字。


Identify Launch-Time Factors: Static Initializers

应用程序中的某些代码必须在iOS运行应用程序的main()函数之前运行,这会增加启动时间。 该代码包括:

  • C ++静态构造函数。
  • 在类或类别中定义的Objective-C +load方法。
  • 标有clang attribute __attribute__((constructor))的函数。
  • 链接到应用程序或框架二进制文件的__DATA__ mod_init_func区的任何函数。

在可能的情况下,将代码移至应用程序生命周期的后期,即应用程序启动完成后但需要工作结果之前。 在Instruments中,Static Initializer Calls工具测量您的应用程序花费在运行静态初始化程序上的时间。


Identify Launch-Time Factors: UIKit Lifecycle Methods

UIKit初始化您的应用程序代理类(符合UIApplicationDelegate协议的类)的实例,并将其发送给application:willFinishLaunchingWithOptions:application:didFinishLaunchingWithOptions:消息。 UIKit在主线程上发送这些消息,而用这些方法执行代码所花费的时间增加了应用程序的启动时间。使用这些方法仅做准备应用程序初始显示所需的工作;将其他任务推迟到应用程序生命周期中的更合适的时间。

如果在刷新内容时向用户显示陈旧的内容有意义,则将数据模型与网络服务的同步推迟到应用程序运行为止。将同步移到异步后台队列。注册后台任务以从网络服务获取更新,以减少启动时数据的陈旧性和使数据保持最新状态所需的工作量。

在首次使用而不是在应用启动时初始化非视图功能,例如持久性存储和位置服务。仅检索显示应用的初始视图所需的数据。请注意您的应用程序是否正在还原状态,并准备显示正在还原的视图所需的数据。如果未还原任何状态,则仅准备默认的初始视图。例如,默认情况下,图库应用程序可能会显示图像缩略图的集合,并允许用户选择照片以获取详细视图。如果应用程序启动时没有恢复状态,则只需显示一个占位符即可显示一小屏缩略图,并在应用程序启动完成后用真实的图像缩略图填充它们。在用户点击缩略图之一之前,不需要加载完整的详细图像。

初始化已知在首次启动时可行的应用行为的受限子集。例如,任务管理器应用程序可以让用户在启动时创建新任务,即使该应用程序尚未从其持久性存储或网络服务中检索到用户的所有现有任务。


Identify Launch-Time Factors: Drawing Initial View Hierarchy

Xcode OrganizerMetricKit都使用第一帧的时间作为启动时间的度量,包括绘制在第一帧上显示的视图所需的时间。将视图添加到视图层次结构必须限于主线程,因此,具有更多视图的更复杂的视图层次结构比简单层次结构需要更长的渲染时间。

减少应用程序初始视图的复杂性可以缩短加载时间,用标准视图替换重载drawRect:的自定义视图也可以达到缩短时间的效果。在需要自定义绘图的地方,请注意传递给draw(_ :)的矩形,并且仅在该矩形内渲染视图的一部分。这样做可以避免对视图中未渲染到屏幕的部分进行图像解码和计算颜色,坐标和绘图命令。


Track Additional Startup Activities

启动时间度量标准衡量的是从用户点击其主屏幕上的应用程序图标到将应用程序的第一帧绘制到屏幕上的时间。绘制default.png或启动屏幕storyboard的过程在此期间进行,并且其外观不会结束启动时间计数器。

如果您的应用在绘制第一帧之后但在用户开始使用该应用之前仍需要运行代码,则该时间不会影响启动时间指标。额外的启动活动仍然有助于提高用户对应用程序响应能力的认识。

要跟踪其他启动活动,请在应用程序中创建类别为pointsOfInterestOSLog对象。使用os_signpost函数记录应用程序准备任务的开始和结束,如以下示例所示:

class ViewController: UIViewController {
    static let startupActivities:StaticString = "Startup Activities"
    let poiLog = OSLog(subsystem: "com.example.CocoaPictures", category: .pointsOfInterest)

    override func viewDidLoad() {
        super.viewDidLoad()
        os_signpost(.begin, log: self.poiLog, name: ViewController.startupActivities)
        // do work to prepare the view
        os_signpost(.end, log: self.poiLog, name: ViewController.startupActivities)
}

Instruments中,Points of Interest在其时间轴中显示signposts。 您可以使用此信息将应用程序中的活动与应用程序的其他启动任务相关联。

后记

本篇主要讲述了Reducing Your App's Launch Time,感兴趣的给个赞或者关注~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容