使用友盟+U-APM实现iOS App启动优化

作者:武玉宝

一、前言

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

二、启动流程

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

1.pre-main阶段

① 加载应⽤的可执⾏⽂件

② 加载 dyld动态连接器

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

2.main()阶段

① dyld调⽤ main()

② 调⽤ UIApplicationMain()

③ 调⽤ applicationWillFinishLaunching

④ 调⽤ 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⼤部分都是系统库,不需要我们去做额外的优化。

优化结论:

① 尽量不使⽤内嵌的dylib,从⽽避免增加 `Load dylibs`开销

② 合并已有的dylib和使⽤静态库(static archives),减少dylib的使⽤个数

③ 懒加载dylib,但是要注意dlopen()可能造成⼀些问题,且实际上懒加载做的⼯作会更多


1.2 Rebase/Bind

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

优化结论:

在此过程中,我们需要注意的是尽量减少指针数量,⽐如:

① 减少ObjC类(class)、⽅法(selector)、分类(category)的数量

② 减少C++虚函数的的数量(创建虚函数表有开销)

③ 使⽤Swiftstruct(内部做了优化,符号数量更少)

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()函数。

优化结论:

① 少在类的+load⽅法⾥做事情,尽量把这些事情推迟到+initiailize

② 减少构造器函数个数,在构造器函数⾥少做些事情

③ 减少构造器函数个数,在构造器函数⾥少做些事情

2.main()阶段

在这⼀阶段⾥,主要优化重点放在 SDK初始化、业务⼯具注册、整体didFinishLaunchingWithOptions ⽅法中,因为我们的⼀些第三⽅app⻛格配置、启动引导⻚显示状态逻辑、版本更新逻辑等等基本⽅都会在这⾥进⾏,如果这部分逻辑没有做好优化梳理,随着业务不断拓展,臃肿的业务逻辑会直接导致启动时间加⻓。

优化结论:

在满⾜业务需求的前提下,尽量减少 didFinishLaunchingWithOptions ⽅法在主线程中的事件处理逻辑,⽐如:

① 根据实际业务状况,梳理各个⼆⽅/三⽅库,找到可以延迟加载的库,做延迟加载处理,⽐如放到⾸⻚控制器 的viewDidAppear⽅法⾥。

② 梳理业务逻辑,把可以延迟执⾏的逻辑,做延迟执⾏处理。⽐如检查新版本、注册推送通知等逻辑。

③ 避免进⾏⼀些复杂/多余的计算逻辑,这类逻辑尽量进⾏异步延迟处理。

④ 避免在⾸⻚控制器的viewDidLoad和viewWillAppear做太多容易阻塞主线程的事情,这2个⽅法执⾏完,⾸⻚控制器才能显示。

四、场景补充

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

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

即:

1.app更新过程中,⾸先进⾏本地内嵌处理逻辑,内嵌⾸⻚数据结构( localDataBase)、内嵌⾸⻚样式所需资源( localStorage)。

2.在安装启动之后,对本地与线上数据更新记录进⾏对⽐,检测是否需要更新本地内嵌数据结构。

3.检测到有需要更新的数据时,才会对指定结构进⾏静默更新,并且同步更新本地数据结构。

这样做的好处是:

1.⾸⻚数据直接从本地加载,减少⽹络数据等待时间

2.仅检测数据key值变化,⼩数据量对⽐定向更新结构,减少api数据交互频次及数据包体积

3.能够保证⾸⻚对于⽤户来说会⼀直处于⼀个友好的展示状态

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

五、统计时长

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

优化前启动时⻓:

优化后启动时⻓:

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

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

1.启动耗时和次数

2.启动耗时分布

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

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

参考:

探秘 Mach-O ⽂件

iOS 底层 - 从头梳理 dyld 加载流程

iOS app启动 - dyld加载App流程

"file:///D:/Users/robin/Documents/Optimizing_app_startup_time/resource/wwdc2016_optimizing_app_startup_time.pdf">wwdc2016optimizingappstartuptime.pdf

PHP网站源码伊犁企业网站改版多少钱衢州网站改版哪家好曲靖网站设计模板哪家好钦州企业网站建设推荐昭通百度爱采购多少钱内江企业网站设计推荐鹰潭关键词排名包年推广多少钱福永网站改版公司福田网站优化按天收费公司贵阳网站推广工具多少钱常德关键词按天收费珠海百度竞价公司广元seo报价来宾seo价格凉山网站改版赣州网站优化按天计费公司濮阳网站制作阳江百姓网标王推荐孝感外贸网站建设推荐揭阳网站优化排名公司武威网站建设哪家好兴安盟设计网站枣庄seo排名北京网络广告推广推荐张北百搜标王济南网站制作设计价格宁德网站搜索优化报价桂林营销网站南京设计网站公司厦门企业网站设计推荐歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

PHP网站源码 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化