随着项目越做越大,代码和业务量越来越多,这时候每次启动APP的时候就会花费较长的时间,这对用户来说体验很不好。所以,针对APP启动时间的优化还是很有必要的。

关于APP启动时间的分析和优化可以以main()为分界点,分为main()方法执行之前的加载时间(pre-main time)和main()之后的加载时间。那么,如何定量的测量这两个阶段具体的执行时间呢,下面先给出测量方法,看一下自己项目启动时间是否合理:

一、main()方法之前启动时间的测量方法:

在Xcode中添加环境变量参数DYLD_PRINT_STATISTICS即可,这样运行APP时在控制台就会打印出pre-main花费的时间,如下图:

如果想打印详细的pre-main中各个过程花费的时间,可以再添加一个DYLD_PRINT_STATISTICS_DETAILS参数,这时你会看到pre-main time和total time的值不一样,其实下边的total time - debugger pause time就和上边的pre-main time大概一致了。如下图:

PS:如果你想打印dyld装载动态库的顺序,可以设置这个环境变量 DYLD_PRINT_LIBRARIES

二、main()方法之后的启动时间的测量方法:

在main.m文件中,定义一个全局变量:

CFAbsoluteTime startTime;int main(int argc, char * argv[]) {startTime = CFAbsoluteTimeGetCurrent();

在AppDelegate.m文件中didFinishLaunchingWithOptions方法return之前计算时间差:

 double launchTime = CFAbsoluteTimeGetCurrent() - startTime;NSLog(@"launchTime = %f秒",launchTime);

三、main()方法调用之前启动过程的解析:

App开始启动后,系统内核(XNU)首先加载可执行文件(自身App的所有.o文件的集合),然后加载动态链接器dyld,dyld是一个专门用来加载动态链接库的库。 执行从dyld开始,dyld从可执行文件的依赖开始, 递归加载所有的依赖动态链接库。

补充:用户点击图标之后,会发送一个系统调用 execve 到内核,内核创建进程。接着会把主二进制 mmap 进来,读取 load command 中的 LC_LOAD_DYLINKER,找到 dyld 的的路径。然后 mmap dyld 到虚拟内存,找到 dyld 的入口函数_dyld_start(最终调到dyld的_main函数),把 PC 寄存器设置成_dyld_start,接下来启动流程交给了 dyld。)

动态链接库包括:iOS 中用到的所有系统 framework,加载OC runtime方法的libobjc,系统级别的libSystem,例如libdispatch(GCD)和libsystem_blocks (Block)。

总结来说,main()方法调用前,启动过程大体分为如下步骤:

1、内核加载可执行文件

2、load dylibs image (加载程序所需的动态库镜像文件)

3、Rebase image /  Bind image (由于ASLR(address space layout randomization)的存在,可执行文件和动态链接库在虚拟内  存中的加载地址每次启动都不固定,所以需要修复镜像中的资源指针)

4、Objc setup (注册Objc类、将Category中的方法插入方法列表)

5、initializers (调用Objc类的+load()方法、调用C++类的构造函数)

针对上边各个启动过程,我们可以做的优化有:

1、减少动态库的引用,将项目中不使用的Framework及时删除,将Xcode配置中General -> Linked Frameworks and Libraries中使用不到的系统库不再引用。

2、合并动态库。

3、尽量不使用内嵌(embedded)的dylib,加载内嵌dylib性能开销较大。

4、清理项目中冗余的类、category。对于同一个类有多个category的,建议进行合并。

5、将不必须在+load方法中做的事情延迟到+initialize中。

6、尽量不要用C++虚函数(创建虚函数表有开销),不要在C++构造函数中做大量耗时操作。

四、main()方法调用之后过程的解析:

main()方法调用之后,主要是didFinishLaunchingWithOptions方法中初始化必要的服务,显示首页内容等操作。这时候我们可以做的事情主要有:

1、将一些不影响首页展示的服务放到其他线程中去处理,或者延时处理和懒加载。延时处理可以监听Runloop的状态,当进入kCFRunLoopBeforeWaiting(即将休眠状态)再去处理任务,最大限度的利用CPU等系统资源。

2、使用Xcode的Instruments的Time Profiler工具,分析启动过程中比较耗时的方法和操作,然后,进行具体的优化。

3、重点关注TabBarController和首页的性能,保证尽快的能展示出来。这两个控制器及里边的view尽量用代码进行布局,不使用storyboard和xib,如果在布局上想更进一步的优化,那就连autolayout(Massonry)都不要使用,直接使用frame进行布局。

4、本地缓存。首页的数据离线化,优先展示本地缓存数据,等待网络数据返回之后更新缓存并展示。

以上就是关于iOS客户端启动优化的相关总结,如有不同意见或者更好的方案,欢迎沟通交流。

参考:

iOS启动时间优化

今日头条iOS客户端启动速度优化

iOS App从点击到启动(介绍系统架构和底层知识较多)

APP从编译到链接再到启动的过程

2022年更新:

抖音品质建设 - iOS启动优化之原理篇_字节跳动技术团队官方博客-CSDN博客

iOS启动速度优化总结相关推荐

  1. iOS启动速度优化实践分享

    一款App的启动速度,不单单只有用户体验这一方面,往往还决定了它能否收获更多的用户.这就好像陌生人第一次碰面,第一感觉往往决定了他们接下来是否会继续交往.由此可见,启动速度的优化必然是App开发过程中 ...

  2. iOS 性能优化总结

    原文链接:https://github.com/skyming/iOS-Performance-Optimization 关于 iOS 性能优化梳理: 基本工具.业务优化.内存优化.卡顿优化.布局优化 ...

  3. 关于iOS应用启动速度优化

    前言 不积跬步,无以至千里;不积小流,无以成江海.--荀子 关于App应用启动速度优化的话题:Session 406 Optimizing App Startup Time ,该Session上App ...

  4. 抖音品质建设 - iOS启动优化《实战篇》

    前言 启动是 App 给用户的第一印象,启动越慢,用户流失的概率就越高,良好的启动速度是用户体验不可缺少的一环.启动优化涉及到的知识点非常多,面也很广,一篇文章难以包含全部,所以拆分成两部分:原理和实 ...

  5. 爱奇艺技术分享:爱奇艺Android客户端启动速度优化实践总结

    本文由爱奇艺技术团队原创分享,原题<爱奇艺Android客户端启动优化与分析>. 1.引言 互联网领域里有个八秒定律,如果网页打开时间超过8秒,便会有超过70%的用户放弃等待,对Andro ...

  6. Android启动速度优化

    欢迎访问我的个人网站:https://coderyuan.com 最近做了一些Android App启动速度的优化,有一些心得,整理整理 影响启动速度的原因 高耗时任务 数据库初始化.某些第三方框架初 ...

  7. 抖音品质建设 - iOS启动优化之原理篇

    前言 启动是 App 给用户的第一印象,启动越慢用户流失的概率就越高,良好的启动速度是用户体验不可缺少的一环.启动优化涉及到的知识点非常多面也很广,一篇文章难以包含全部,所以拆分成两部分:原理和实战. ...

  8. iOS 滑动性能优化

    iOS 滑动性能优化 目录 一. 减少图层的Blend操作 1. UIView的背景色避免使用clearColor 2. 控件贴图避免使用带alpha的图片 3. UIImageView 使用时避免半 ...

  9. Android内核开发:系统启动速度优化

    在学习新知识的过程中,我一直很推荐结合实战任务去学习,只有经历实战,才能加深对理论知识的理解.<Android内核开发>系列已经写了八篇了,本文就结合前面的内容,给大家布置一个实战任务:  ...

最新文章

  1. iOS开发 AVAudioPlayer
  2. easyUI parser的使用
  3. 控件中的Events个人理解。
  4. java栈顶元素_栈在Java类库中的实现
  5. 计算机网络————P1 概念、组成、功能和分类
  6. 魔天记服务器维护,魔天记3月23日维护公告
  7. iOS开发之原生二维码扫描rectOfInterest扫描区域
  8. jsp页面输出excel文件乱码解决方案
  9. Python学习 Day 039 - HTML
  10. ExtJS入门到精通视频教程下载 ExtJS视频教程
  11. 手机、电话号码、邮箱、域名、身份证号的测试用例
  12. window重命名图片不带括号
  13. 酒店管理系统——界面设计
  14. 线性代数-矩阵方程应用:配平化学方程式
  15. firefoxos中打开app
  16. mini-batch Gradient Descent
  17. 详解VMware12安装Mac OS X 10.11
  18. ARM7开发板模拟器Skyeye安装设置全攻略
  19. python修改图片名称
  20. readv和writev

热门文章

  1. springboot项目使用advice做统一返回
  2. 十分经典的windows批处理教程 (文笔很不错呢)
  3. 雅思作文模板.html,雅思作文模板使用分析
  4. 案例 | 深入了解捷尼赛思GV60的数字座舱
  5. 计算机基础知识考题及答案,计算机基础知识试题及答案(一)
  6. python二级第十二套答案
  7. alipay.trade.app.pay
  8. update多表联合更新
  9. 下一代Linux文件系统,存储那些事儿(二): 下一代Linux文件系统BTRFS简介
  10. 小土堆pytorch教程学习笔记P8P9