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

yy.png

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

优化结论:

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

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

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

1.2 Rebase/Bind

yy.png

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

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

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

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

3、使⽤ Swift struct (内部做了优化,符号数量更少)

1.3 Objc setup

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

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

yy.png

1.4 Initializers

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

优化结论:

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

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

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

main()阶段

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

优化结论:

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

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

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

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

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

场景补充

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

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

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

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

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

这样做的好处是:

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

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

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

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

统计时长

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

yy.png

优化前启动时⻓:

yy.png

优化前启动时⻓:

yy.png

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

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

yy.png

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

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

相关文章
|
12天前
|
存储 前端开发 安全
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
105 5
|
14天前
|
运维 iOS开发 Windows
windows电脑备案ios APP获取公钥和证书指纹Sha-1值的方法
在阿里云进行APP备案、在备案IOS端的环节的时候,发现需要我们将p12证书安装在电脑上,再用xcode或或钥匙串访问来获取这个证书的公钥和sha-1值。 但是大部分开发uniapp应用的同学们,或者进行发布的运维人员的电脑都是windows,无法按照阿里云的教程来获取ios的公钥和sha-1。备案就被卡主了。 这里介绍下另一个方法,就是使用香蕉云编来在线上传证书获取。如下图所示,打开香蕉云编后,找到下图这个功能
160 0
|
4月前
|
存储
《仿盒马》app开发技术分享--未完成订单列表展示逻辑优化(61)
上一节我们实现订单与优惠券的联合提交时,我去到订单列表页面查看生成的订单信息,发现现在的订单从信息展示到价格计算全都是有问题的。所以紧急的把对应的问题修改一下。
189 70
|
4月前
|
数据库
《仿盒马》app开发技术分享-- 优惠券逻辑优化(58)
我们已经实现了优惠券的领取和展示,现在已经趋近于一个完整的电商应用了,但是这时候问题又来了,我们领取完优惠券之后,我们的新用户优惠券模块依然存在,他并没有消失,既然我们是从云数据库中查询的数据,那么我们需要找到一个字段跟他对应起来,来实现新用户领券后关闭这个模块的展示,同时我们在未登录的时候他也要保持隐藏,登录后能实现优惠券的领取。然后在结算的时候得出有几张符合的券能用
105 9
|
3月前
|
人工智能 IDE 前端开发
写给尊贵的 Tare Pro 用户的喂饭级 IOS APP 开发指南
本文介绍了如何利用 AI IDE Trae,从零开始快速开发一个 iOS 应用《回声》。通过 AI 辅助完成需求梳理、原型设计、编码与调试,展示了 AI 在整个开发流程中的强大助力。
257 0
|
4月前
《仿盒马》app开发技术分享-- 逻辑优化第三弹(83)
现在我们的app功能已经趋近完善,bug和缺失的细节也越来越少了,我们继续对app进行优化,首先是我们的积分页面,我们只实现了全部的积分展示内容,对收入和支出的积分明细并没有进行展示,这里我们要实现一下,然后就是我们的优惠券,我们已过期的优惠券并没有修改状态为已过期。
93 0
|
4月前
《仿盒马》app开发技术分享-- 个人中心页优化(62)
上一节我们实现了订单逻辑的优化,现在我们的app功能更加的完善了,并且随着我们的迭代逻辑疏漏越来越少,现在我们继续进行优化,在之前的业务逻辑中我们的个人中心页面展示了用户的余额以及积分商城入口,这里我们要展示余额准确的值,积分商城的入口我们修改为积分相关的功能入口。并且展示当前账号的积分余额
82 0
|
4月前
|
存储 安全
《仿盒马》app开发技术分享-- 购物车逻辑优化(39)
我们的app主要购物功能已经开发的相对来说比较完善了,接下来就针对各个功能的逻辑性进行迭代和修改,让我们的程序更加的健壮,减少一些逻辑上的bug
79 0
|
7月前
|
Swift iOS开发 开发者
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
693 13
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
|
7月前
|
存储 数据安全/隐私保护 开发者
苹果app上架app store 之苹果开发者账户在mac电脑上如何使用钥匙串访问-发行-APP发布证书ios_distribution.cer-优雅草卓伊凡
苹果app上架app store 之苹果开发者账户在mac电脑上如何使用钥匙串访问-发行-APP发布证书ios_distribution.cer-优雅草卓伊凡
240 8
苹果app上架app store 之苹果开发者账户在mac电脑上如何使用钥匙串访问-发行-APP发布证书ios_distribution.cer-优雅草卓伊凡

热门文章

最新文章

  • 1
    iOS|记一名 iOS 开发新手的前两次 App 审核经历
    158
  • 2
    iOS各个证书生成细节
    257
  • 3
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    854
  • 4
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    313
  • 5
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    230
  • 6
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    245
  • 7
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    259
  • 8
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    490
  • 9
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    1069
  • 10
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    887