优化 App 的启动速度
App 的启动速度不仅影响我们调试,也直接关系到用户体验。之前有些很久没有打开过的项目,需要花费很长的时间才完成编译;对应的 App 在点击后,许久才出现启动画面。你是否为这些问题苦恼过呢?
这是我观看 WWDC2016 Sessions406 《Optimizing App Start Time》的博客笔记。虽然没有字幕听起来很吃力,但光看 Slide 还是有不少收获的。原文有点长,包括理论是实践两部分,为了方便阅读这里只放出一部分。
Mach-O 文件是如何被加载的
在 mian() 函数执行之前,操作系统为我们做了什么?
exec() -> main()
exec()执行过程:
内核随机分配一段可用的内存给应用程序。但有个规则,即不分配低地址的内存空间,该地址空间大小由处理器的位数决定,情况如下:
32位处理器保留 4K
64位处理器保留 4G
低地址保留,用于保存空指针、异常错误信息等。
加载动态库
内存分配完成后,处理器运行动态加载器(Dynamic loader)来加载动态依赖库(dylibs)。
加载过程:
映射所有的直接依赖库,递归间接调用的依赖库(Map all dependent dylibs,recurse).
重建所有的图片(Rebase all images).
绑定所有图片(Bind all images).
准备代码层面的加载(ObjC prepare images)
执行初始化方法(Run initializes).
直接加载:
解析所有的动态库
找出需要的 mach-O 文件
打开并读取文件
认证 mach-O 文件
登记代码签名
为每个 segment 调用
mmap()
映射函数
递归加载:
当所有直接依赖库加载完毕后,还存在直接依赖库依赖于其他库的情况。递归加载间接依赖库,一般 App 需要加载 100 到 400 个动态库!其中绝大多数为系统库,苹果已经最优化了系统库的加载。
2. 重建(Rebasing)
将图片资源根据其地址进行加载,重建信息被编码在 LINKEDIT
segment 中。重建的过程按照地址顺序执行,所以可以被内核预取。
3. 绑定(Binding)
应用程序对动态库的引用只是字符层(symbol)面上,绑定过程中需要加载器通过函数名来查找,相对于重建这个过程需要更多的计算。
4. ObjC 准备阶段
完成重建和绑定后的配置工作
登记定义的 ObjC 类
更新实例变量对应的内存位置
分类的方法被插入到主类
5. 初始化(Initializer)
静态分配内存的对象的初始化
调用 +load 方法
调用相关联的动态库
最后,执行 main()函数
启动优化
对于不同的设备启动速度都不相同,苹果认为完美的启动时间是在 400 毫秒以内。App 的最大允许启动时间为20秒,如果超过这个时间就会被 Killed。
我们可以通过编辑工程的 Schemes 来打印 App 的启动中各项时间花费,从而来分析和优化启动过程。
在 Arguments -> Environment Variables 中加入 DYLY_PRINT_STATISTICS
。
设置后,控制台部分项时间花费输出:
1. 加载动态库
加载动态库需要很大的开销,解决方法是尽可能减少引入不必要的动态库,合并现有可操作的动态库,使用静态文件,使用懒加载等
2. 重建和绑定过程
减少指针变量的使用
减少 Objective-C 类
减少 C++ 虚基类的使用(少见)
建议使用 Swift 结构体
尽可能将属性设置为只读
3. 初始化
将
+load
函数的操作尽可能在+initialize
方法中执行简化 C++ 构造函数
不要在初始化方法里面调用
dlopen()
不要在初始化方法里面创建线程
+initialized
会在任何类加载之前被调用,而 +load
是所在类被加载到系统的时候被调用,这通常比 +initialized
调用的时机要早。在 +load
函数里面做操作会延缓系统的启动时间。
dlopen()
函数用于打开 Bundle 尽可能的延迟读取本地的 Bundld 资源,也有利于加快启动速度。
线程的创建需要很大的开销,不要在 App 启动的过程创建子线程。
参考阅读
1. https://developer.apple.com/videos/play/wwdc2016/406/
2. http://objccn.io/issue-6-3/
3. https://code.facebook.com/posts/1675399786008080/optimizing-facebook-for-ios-start-time/
优化 App 的启动速度的更多相关文章
- Android性能优化-App启动优化
原文地址:https://developer.android.com/topic/performance/launch-time.html#common 通常用户期望app响应和加载速度越快越好.一个 ...
- 优化 App 的启动时间
这是一篇 WWDC 2016 Session 406 的学习笔记,从原理到实践讲述了如何优化 App 的启动时间. App 运行理论 main() 执行前发生的事 Mach-O 格式 虚拟内存基础 M ...
- Android性能优化-App后台优化
原文链接 Background Optimizations 前言 后台进程是内存和电池敏感的.一个隐式的broadcast可能会启动很多监听它的后台进程,即使这些进程可能做得工作不多.这可能丢设备性能 ...
- 怎样优化app,看Facebook怎样做
周四,Facebook Engineering blog 发表了一篇名为<Improving Facebook on Android>博文.博文从四个方面(Performance,Data ...
- WWDC2018 之 优化 App Assets Optimizing App Assets
该篇博客记录了观看WWDC Session227<Optimizing App Assets>的内容以及一些理解. 引言 该session主要讲述了使用Assets Catalog的新特性 ...
- 如何优化 App 的启动时间
http://www.cocoachina.com/ios/20161102/17931.html App 运行理论 main() 执行前发生的事 Mach-O 格式 虚拟内存基础 Mach-O 二进 ...
- iOS 如何优化 App 的启动时间
App 运行理论 main() 执行前发生的事 Mach-O 格式 虚拟内存基础 Mach-O 二进制的加载 理论速成 Mach-O 术语 Mach-O 是针对不同运行时可执行文件的文件类型. 文件类 ...
- [Android Memory] Android Zipalign zip对齐优化app程序
转载地址:http://www.cnblogs.com/xirihanlin/archive/2010/04/12/1710164.html 参考文章:http://www.cnblogs.com/l ...
- 5个可以帮你优化App的优秀网站
也许现在有一款App可以提供所有你需要的,你不需要的,或者你可以想象到的内容.但是,有多少App真的可以不仅满足需求而且还能提供很好的用户体验呢? 相信很多APP并没有这样的能力.有一些APP的设计特 ...
随机推荐
- Openstack之Swift架构(Cloud Storage)
Swift是OpenStack的子项目之一,也称为对象储存,适用于储存永久类型的静态数据,例如:虚拟机镜像文件.图片.存档备份等 复制的三个副本如何联系在一起? 让我们用一些具体场景和介绍一些组件,来 ...
- HDU 1525 Euclid's Game (博弈)
Euclid's Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- POJ1651Multiplication Puzzle(区间DP)
比较好做的区间DP 状态转移方程:DP[i][j] 表示区间[i,j]最小的乘积和. DP[i][j] = MIN{DP[i][k-1]+DP[k+1][j] + a[k]*a[i-1]*a[j+1] ...
- Max retries exceeded with url
78 Traceback (most recent call last): File "thread072413.py", line 163, in <module> ...
- jsp页面加载readyState的五种状态根据我们状态添加进度条
这段代码放在页面最下面 原文如下: document.onreadystatechange = subSomething;//当页面加载状态改变的时候执行这个方法. function subSomet ...
- PL/SQL devloper 常用设置
1)代码自动完成 Tools->Preferences->User Interface->Key Configuration. 找到Tools/Code Assistant,修改为自 ...
- Pyqt5.2.1生成的.ui文件转换成.py
cmd C:\>pyuic5 ui文件路径 -o 要生成的py文件路径 如下: C:\>pyuic5 c:\python33\lib\site-packages\pyqt5\uic\log ...
- sql waitfor 延时执行
看MSDN:http://msdn.microsoft.com/zh-cn/library/ms187331.aspx 语法为: WAITFOR { DELAY 'time_to_pass' | TI ...
- UI:UITableView表视图
表视图 UITableView,iOS中最重要的视图,随处可⻅见. 表视图通常⽤用来管理⼀一组具有相同数据结构的数据. UITableView继承⾃自UIScrollView,所以可以滚动,表视图的每 ...
- document.compatMode(判断当前浏览器采用的渲染方式)
转载自:http://www.cnblogs.com/fullhouse/archive/2012/01/17/2324706.html IE对盒模型的渲染在 Standards Mode和Quirk ...