iOS启动速度优化总结
随着项目越做越大,代码和业务量越来越多,这时候每次启动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启动速度优化总结相关推荐
- iOS启动速度优化实践分享
一款App的启动速度,不单单只有用户体验这一方面,往往还决定了它能否收获更多的用户.这就好像陌生人第一次碰面,第一感觉往往决定了他们接下来是否会继续交往.由此可见,启动速度的优化必然是App开发过程中 ...
- iOS 性能优化总结
原文链接:https://github.com/skyming/iOS-Performance-Optimization 关于 iOS 性能优化梳理: 基本工具.业务优化.内存优化.卡顿优化.布局优化 ...
- 关于iOS应用启动速度优化
前言 不积跬步,无以至千里;不积小流,无以成江海.--荀子 关于App应用启动速度优化的话题:Session 406 Optimizing App Startup Time ,该Session上App ...
- 抖音品质建设 - iOS启动优化《实战篇》
前言 启动是 App 给用户的第一印象,启动越慢,用户流失的概率就越高,良好的启动速度是用户体验不可缺少的一环.启动优化涉及到的知识点非常多,面也很广,一篇文章难以包含全部,所以拆分成两部分:原理和实 ...
- 爱奇艺技术分享:爱奇艺Android客户端启动速度优化实践总结
本文由爱奇艺技术团队原创分享,原题<爱奇艺Android客户端启动优化与分析>. 1.引言 互联网领域里有个八秒定律,如果网页打开时间超过8秒,便会有超过70%的用户放弃等待,对Andro ...
- Android启动速度优化
欢迎访问我的个人网站:https://coderyuan.com 最近做了一些Android App启动速度的优化,有一些心得,整理整理 影响启动速度的原因 高耗时任务 数据库初始化.某些第三方框架初 ...
- 抖音品质建设 - iOS启动优化之原理篇
前言 启动是 App 给用户的第一印象,启动越慢用户流失的概率就越高,良好的启动速度是用户体验不可缺少的一环.启动优化涉及到的知识点非常多面也很广,一篇文章难以包含全部,所以拆分成两部分:原理和实战. ...
- iOS 滑动性能优化
iOS 滑动性能优化 目录 一. 减少图层的Blend操作 1. UIView的背景色避免使用clearColor 2. 控件贴图避免使用带alpha的图片 3. UIImageView 使用时避免半 ...
- Android内核开发:系统启动速度优化
在学习新知识的过程中,我一直很推荐结合实战任务去学习,只有经历实战,才能加深对理论知识的理解.<Android内核开发>系列已经写了八篇了,本文就结合前面的内容,给大家布置一个实战任务: ...
最新文章
- [POI2009]KAM-Pebbles BZOJ1115 [ 待填坑 ] 博弈
- GAN的理解与TF的实现
- 《迷人的8051单片机》----3.4 程序
- github命令行操作
- 创业者:创业要疯狂融资要理性
- AndroidStudio 3.0升级之compile、implementation简要说明
- STM32 设置片外SRAM分散加载
- Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp
- c#用canny算子做边缘提取_干货 | 边缘检测
- Linux下启动、停止J2SE程序(脚本)
- server端多个文件的压缩 .NET
- some any oracle,Oracle Any/Some运算符
- 加快pip下载的速度---镜像
- masscan for windows windows编译masscan
- Power BI Desktop 中的数据源
- Android Studio 4.0 新建项目gradle依赖base sdk以后报错 ‘assets/cfg/*‘ collided 的解决办法
- 我的世界我服务器注册密码大全,我的世界国际版账号密码大全2021
- django {%url %}传递参数 url 传参 报错
- mysql三m架构为什么_AnalyticDB for MySQL 3.0 技术架构解析
- 向腾讯企业邮箱发送邮件失败,报错: 559
热门文章
- cross-entropy for one-stage detecor
- 对发了offer,而没有来入职的应聘者,现在再次来应聘,如果你是面试官,你会录用吗?...
- 关于装有WIN7系统的硬盘转移到USB3.0移动硬盘盒后开机启动蓝屏(代码7B)的解决方案
- Linux NTP时钟同步
- 风雨十年路,历历在眼前,今做离职语,感慨有万千!-------来自一位中兴长天java十年的总工程师
- 基于centos 安装配置环境
- Linux下Socket网络编程之点对点聊天室
- 用‘+‘替换字符串中的所有空格[复制]
- websphere mq 8死信队列测试--队列满了场景
- 爱尔康与好大夫在线达成合作​;武田达泽优获批进入中国 | 跨国药企在中国...