iOS--App启动过程及优化

前言

App启动是用户对于一个app的第一印象,因此如何使用户在最短的时间打开进入app显得格外重要。启动优化因此成为了App调优至关重要的一项。

只有具体了解了App的启动过程,我们才能对其进行优化。

App启动过程

App启动分为冷启动和热启动

  • 热启动:App刚结束后再启动,有部分在内存但没有进程存在。
  • 冷启动:启动时,App的进程不在系统里,需要开启新进程。

我们所做的优化都是针对于冷启动,即app第一次启动或是kill掉之后重新打开,不在内存里也没有进程存在。

APP冷启动可以概括为三个阶段

  • 1、dyld:加载镜像,动态库
  • 2、RunTime方法
  • 3、main函数初始化

1、dyld

dyld(dynamic link editor),app的动态链接器,可以用来装在Mach-O文件(可执行文件、动态库等)

启动APP时,dyld所做的事情有

真正的加载过程从exec()函数开始,exec()是一个系统调用。操作系统首先为进程分配一段内存空间,然后执行如下操作:

  • 1、把App对应的可执行文件加载到内存。
  • 2、把Dyld加载到内存。
  • 3、Dyld进行动态链接。

具体内容

  • 1、加载动态库
    • Dyld从主执行文件的header获取到需要加载的所依赖动态库列表,然后它需要找到每个 dylib,而应用所依赖的 dylib 文件可能会再依赖其他 dylib,所以所需要加载的是动态库列表一个递归依赖的集合
  • 2、Rebase和Bind
    • 1、Rebase在Image内部调整指针的指向。在过去,会把动态库加载到指定地址,所有指针和数据对于代码都是对的,而现在地址空间布局是随机化,所以需要在原来的地址根据随机的偏移量做一下修正
    • 2、Bind是把指针正确地指向Image外部的内容。这些指向外部的指针被符号(symbol)名称绑定,dyld需要去符号表里查找,找到symbol对应的实现

2、RunTime方法

在Dyld阶段加载结束以后就进入了RunTime阶段

  • 1、Objc setup
    • 1、注册Objc类 (class registration)
    • 2、把category的定义插入方法列表 (category registration)
    • 3、保证每一个selector唯一 (selector uniquing)
  • 2、Initializers
    • 1、Objc的+load()函数
    • 2、C++的构造函数属性函数
    • 3、非基本类型的C++静态全局变量的创建(通常是类或结构体)

3、main函数初始化

APP的启动由dyld主导,将可执行文件加载到内存,顺便加载所有依赖的动态库 并由runtime负责加载成objc定义的结构 所有初始化工作结束后,dyld就会调用main函数 接下来就是UIApplicationMain函数,AppDelegate的application:didFinishLaunchingWithOptions:方法

这个里面往往是最占用启动时间的地方,同时也是我们最为可控的地方。

• 进入 main() 函数,启动应用。

• 执行 UIApplicationMain() 函数,创建 UIApplication 对象并设置 AppDelegate。

• 加载应用的主 UI,包括 storyboard 或 xib 文件,以及 AppDelegate 的各种生命周期方法,如 application:didFinishLaunchingWithOptions:。

4.首屏渲染阶段

• 初始化 rootViewController,加载和渲染界面。

• 渲染完成后,用户将看到应用的首屏。

总结:iOS App冷启动的流程分为以下四步:

1. dyld 加载阶段:

• 动态链接器 dyld 负责加载应用的可执行文件及其依赖的动态库。此时,系统将会做如下工作:

• 查找应用的可执行文件和动态库

• 将它们加载到内存中

• 进行符号解析和绑定

• 执行初始化函数(如 +load 方法和静态构造函数)

2. runtime 初始化阶段:

• ObjC 运行时对类和分类进行注册。

• 执行各类 +load 方法,这个阶段还会进行一些 Swift 类的初始化。

3. main() 函数执行阶段:

• 进入 main() 函数,启动应用。

• 执行 UIApplicationMain() 函数,创建 UIApplication 对象并设置 AppDelegate。

• 加载应用的主 UI,包括 storyboard 或 xib 文件,以及 AppDelegate 的各种生命周期方法,如 application:didFinishLaunchingWithOptions:。

4. 首屏渲染阶段:

• 初始化 rootViewController,加载和渲染界面。

• 渲染完成后,用户将看到应用的首屏。

冷启动时间优化

  1. 减少动态库的数量

动态库越多,dyld 加载的时间越长。

  1. 延迟初始化

尽量延迟一些不必要的初始化工作,不要在启动时立即初始化所有对象。可以使用懒加载将一些初始化放到用户需要时再进行,以减轻启动阶段的负担。

  1. 避免 +load方法的使用

+load 方法会在 dyld 加载阶段执行,建议用 +initialize 或者在合适的地方延迟执行初始化逻辑,避免阻塞启动流程。

4.优化AppDelegate:

application:didFinishLaunchingWithOptions: 方法应保持精简,避免在这里进行耗时的操作。将一些耗时任务放到后台队列中异步执行。

5.减少主线程阻塞

启动阶段尽量避免主线程的耗时操作,如文件 I/O、网络请求等。将这些操作放到子线程处理,以免阻塞界面渲染。

6.预编译和瘦身

移除未使用的代码、图片等资源,精简应用的体积,从而减少加载时间。

尽量减少 storyboard 的使用,尤其是大而复杂的 storyboard,可以分解成多个小的 storyboard 或者使用纯代码实现界面。

7.启动时的网络请求

尽量避免在启动时进行同步的网络请求,如果必须请求,可以在启动完成后或在后台进行异步请求,以减少对启动时间的影响。

参考:

https://github.com/SunshineBrother/JHBlog/blob/master/iOS%E7%9F%A5%E8%AF%86%E7%82%B9/iOS%E5%A4%A7%E6%9D%82%E7%83%A9/APP%E5%90%AF%E5%8A%A8%E4%BC%98%E5%8C%96/App%E5%90%AF%E5%8A%A8%E6%97%B6%E9%97%B4%E4%BC%98%E5%8C%96.md

IOS App冷启动优化_ios冷启动优化-CSDN博客

相关推荐
chaosama24 分钟前
禁止uni小程序ios端上下拉伸(橡皮筋效果)
ios·小程序
Zender Han41 分钟前
Flutter自定义矩形进度条实现详解
android·flutter·ios
S0linteeH1 小时前
iOS 18.2 六大新功能外媒實測|ChatGPT進化版SIRI、自製Genmoji
ios
DisonTangor19 小时前
苹果发布iOS 18.2首个公测版:Siri接入ChatGPT、iPhone 16拍照按钮有用了
ios·chatgpt·iphone
- 羊羊不超越 -19 小时前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
2401_865854881 天前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone
HackerTom2 天前
iOS用rime且导入自制输入方案
ios·iphone·rime
良技漫谈2 天前
Rust移动开发:Rust在iOS端集成使用介绍
后端·程序人生·ios·rust·objective-c·swift
2401_852403552 天前
高效管理iPhone存储:苹果手机怎么删除相似照片
ios·智能手机·iphone
星际码仔2 天前
【动画图解】是怎样的方法,能被称作是 Flutter Widget 系统的核心?
android·flutter·ios