iOS App 启动优化

网络
作为程序猿来说,“性能优化”是我们都很熟悉的词,也是我们需要不断努以及持续进的事情,本文将会以iOS App的启动优化为展开点进探讨。

前言

作为程序猿来说,“性能优化”是我们都很熟悉的词,也是我们需要不断努以及持续进的事情;其实优化是个很严谨的课题,因为细分来说的话有种优化向 ,但是切忌在实际开发过程中不能盲目的为了优化而优化,这样有时可能会造成适得其反的负效果,需要我们根据实际场景以及业务需求进合理优化。接下来进入正题,本文将会以iOS App的启动优化为展开点进探讨。

启动流程:

iOS App 的启动我们都知道分为pre-main 和 main() 两个阶段,并且在这两个阶段中,系统会进行系列的加载操作,过程如下:

1、pre-main阶段

1. 加载应的可执件

2. 加载dyld动态连接器

3. dyld递归加载应所有依赖的动态链接库dylib

2、main()阶段

1. dyld调 main()

2. 调UIApplicationMain()

3. 调applicationWillFinishLaunching

4. 调didFinishLaunchingWithOptions

阶段优化项

1、pre-main阶段

针对 pre-main 阶段做优化时,我们需要先详细了解其加载过程,这个可以在2016年WWDC 的 Optimizing App Startup Time 中详细了解到, 相关材料

1.1 Load dylibs

这阶段dyld分析应依赖的 dylib (xcode7以后.dylib已改为名.tbd),找到其 mach-o 件,打开和读取这些件并验证其有效性,接着会找到代码签名注册到内核,最后对 dylib 的每个 segment 调 mmap()。不过这的 dylib 部分都是系统库,不需要我们去做额外的优化。

优化结论

1.2 Rebase/Bind

在dylib的加载过程中,系统为了安全考虑,引了ASLR (Address Space Layout Randomization)技术和 代码签名。由于ASLR的存在,镜像(Image,包括可执件、 dylib和bundle)会在随机的地址上加载,和 之前指针指向的地址(preferred_address)会有个偏差(slide), dyld需要修正这个偏差,来指向正确的 地址。 Rebase在前, Bind在后, Rebase做的是将镜像读内存,修正镜像内部的指针,性能消耗主要在 IO。 Bind做的是查询符号表,设置指向镜像外部的指针,性能消耗主要在CPU计算。

优化结论:

1.3 Objc setup

部分ObjC初始化作已经在Rebase/Bind阶段做完了,这步dyld会注册所有声明过的ObjC类,将分类插 到类的法列表,再检查每个selector的唯性。

在这步倒没什么优化可做的, Rebase/Bind阶段优化好了,这步的耗时也会减少。

1.4 Initializers

在这阶段, dyld开始运程序的初始化函数,调每个Objc类和分类的+load法,调C/C++ 中的构造器 函数(attribute((constructor))修饰的函数),和创建基本类型的C++静态全局变量。 Initializers阶段执 完后, dyld开始调main()函数。

优化结论:

2、main()阶段

在这阶段,主要优化重点放在 SDK初始化、业务具注册、整体

didFinishLaunchingWithOptions 法中,因为我们的些第三 app 格配置、启动引导显示状态逻辑、版本更新逻辑等等基本都会在这进,如果这部分逻辑没有做好优化梳理,随着业务不断拓展,臃肿的业务逻辑会直接导致启动时 间加。

场景补充:

另外,在我们实际开发过程中,很多项的控制器都会有些后台可配、较为丰富的结构或者推荐数据 进展示,且我们的展示速度通常也会被纳启动优化的部分,其实对于这种类型的优化,如果我 们还只是传统的 api -> data -> UI 式进的话,就很难有明显的改善空间,因为户的络状态 并不是可控项,如果不做其他处理的话,那在很多场景下对户来说,即使我们放上些占位图,展示的样式也是很不友好的,毕竟控制器对户的第视觉冲击影响还是较的。

对于这种场景下的优化来说,般我们可以采取 Local + Network + Update 的式在定程度上优化 加载速度: 即:

这样做的好处是

当然这种也并不是唯的应对式,且也并对所有场景都适,只是提供种思路已,还是需要根据 项的实际场景选择适合的优化案。

统计时

另外如果在开发过程中,我们想直观的查看 app 启动期间,各阶段的耗时情况,也可以在Xcode,的 edit scheme 设置添加 DYLD_PRINT_STATISTICS 为1 ,打印启动时,例如

优化前启动时:

优化后启动时:

当然,这些log我们仅仅只能在开发调试阶段查看打印,那么在实际项中,我们需要对线上项的启动数据 进监控,以便及时的定位和优化那些影响 app 启动时的环节,这时我们应该怎样更好的处理呢?

当然我们可以通过服务器埋点上报的式统计分析,不过这样来会发现我们的统计成本就会增 加,且结果分析也会变得不那么灵活。所以这推荐种简单的监控式,那就是友盟的 U-APM 应能性 能监控SDK ,只需要我们进简单的pod集成之后,便可根据我们的实际需要进动或者动监控启动数 据,详情可以参考 U-APM, 并且为了便我们对数据进分析,友盟后台已经根据这些数据帮我们绘制出 了对应的分布图,我们可以了然的得出启动耗时分布、启动类型占等等,如图:

除此之外,我们还可以通过SDK进崩溃分析、 ANR分析、监控告警、卡顿分析、内存分析等等诸多功能, 有了 U-APM 这个监控平台,其实在实际开发过程中很程度的提升了我们对线上 app 的优化分析效率。

当然本的介绍也只是较浅显的优化项,仅供参考以及思路引导,优化之路任重道远,还需要我们不断 的去探索、发现、提。不过最后还是要提醒句:在实际项开发过程中,不要为了优化优化,要根据 项情况有针对性的进优化。

责任编辑:梁菲 来源: 阿里云云栖号
相关推荐

2017-01-23 21:05:00

AndroidApp启动优化

2018-09-29 15:59:18

APPiOS优化

2018-12-07 12:54:22

App美团外卖iOS客户端

2021-06-28 14:35:36

iOSAPP缓存

2023-08-30 18:49:05

2016-11-08 19:43:58

Android

2021-07-12 23:43:46

AppAndroid优化

2015-02-28 09:49:22

lua

2017-02-14 17:00:39

iOSApp内存优化

2013-09-02 10:33:44

苹果开发者iOS 7

2017-08-31 14:40:54

Linuxinit进程app启动

2019-12-13 10:25:08

Android性能优化启动优化

2013-10-16 15:36:53

iOS优化

2013-12-17 16:21:17

iOSiOS性能优化

2015-07-09 15:04:53

JSPatch动态更新ios app

2009-09-08 09:45:23

App Engine性

2022-08-25 06:42:00

飞书GCD 队列启动优化

2015-01-22 14:12:40

Android源码APP启动引导

2015-05-30 10:04:24

线下公开课51CTO沙龙MDSA

2015-11-04 10:15:45

iOS 后台进程监听
点赞
收藏

51CTO技术栈公众号