“我报名参加金石方案1期应战——分割10万奖池,这是我的第1篇文章,点击检查活动概略”
一、 APP 发起类型
APP发起分为 冷发起
、热发起
两种
-
冷发起
: APP的icon从点击发起前,它的进程不在系统里,需求新创建一个进程分配给它的发起的情况。 -
热发起
: APP在发起后用户将APP退到后台,在APP的进程还在系统里的情况下,用户从头发起进入APP的进程。(这个进程做的作业比较少)
二、APP发起的三个阶段、
pre-main ( main()函数发起之前)
main() 函数之后发起之后
首屏烘托结束
1、pre-main
: ( main()函数发起之前)
此进程是发起第一步,首要包括四个进程:
- 加载动态库耗时 (
dylib loading
):- 修改符号和绑定符号耗时 (
rebase/binding
)- OC类注册 耗时(
ObjC setup time
)- +load()函数耗时 (
initializer
)
这几个进程的耗时,我们能够经过配备环境变量打印出来进行检查:
- 首要我们进入
Edit Scheme
,然后选中Run -> Arguments -> Environment Variables
- 然后配备
key
为:DYLD_PRINT_STATISTICS
- 然后我们发起项目,就会发现xcode会打印出
pre-main
的耗时,每个小进程的耗时都会闪现出来: 下面我们剖析下每个小进程的首要功用:
-
dylib loading
: 首要是载入动态库,这个进程会去加载APP运用到的一切动态库,而动态库之间有自己的依靠联系,所以会消耗时间去查找和读取。
优化
:
尽量运用系统库
: 由于系统的动态库现已做了优化尽量减少动态库的运用
: 动态库运用尽量不要逾越6
个,假设逾越,最好去兼并他们运用将动态库替换为静态库运用
:静态库的运用会简化时间
-
rebase/binding
:rebase
:内部调整指针的指向,Mach-o被加载到内存的时分会添加随机地址(ASLR),这个随机的地址跟代码和数据指向的旧地址会有差错。dyld 需求修改这个差错,做法便是将 dylib 内部的指针地址都加上这个偏移量。binding
:将指针指向镜像(MachO文件)外部的内容,binding便是将这个二进制调用的外部符号进行绑定的进程。
优化:
-
Objc setup
:oc 类的加载 1、读取二进制文件的 DATA 段内容,找到与 objc 相关的信息 2、注册 Objc 类,ObjC Runtime 需求保护一张映射类名与类的全局表。当加载一个 MachO 时,它定义的一切的类都需求被注册到这个全局表中; 3、读取 protocol 以及 category 的信息,把category的定义刺进方法列表 (category registration)
优化:
尽量减少类的运用
:有的地方能够用结构体替代删去无用、扔掉的类
-
initializer
: 函数初始化 1、Objc的 +load()函数调用
2、C++
的结构函数的调用
优化:
尽量减少在+load()
里面添加放法,减少+load()
函数的复杂度 尽量不要用C++虚函数
2、main函数阶段的优化
main函数首要的进程
调用
main 函数
调用UIApplicationMain()
调用applicationWillFinishLaunching
在main
函数之后首要是实行didFinishLaunching
方法,这个方法首要是实行各种业务。可是有些任务不需求当即实行,这时分我能够对其采取推延加载,减少对发起时间的影响。
首要的业务首要分三类:初始化第三方SDK
、环境配备
、自己的工具栏的初始化
,针对这三大类进行优化:
-
减少发起初始化流程
: 针对一些方法流程,能懒加载的懒加载,能推延的推延实行,尽量少占用主线程的发起时间 能运用多线程来初始化的,就运用多线程
尽量防止运用xib/SB搭建UI,最好运用纯代码搭建
删去扔掉的类、方法等
3、首屏加载的优化
上面的两种优化方法,在小项目中都是毫秒级的,能优化的空间不到,效果有时分用户底子看不出来,用户能感知的是从点击图标到使用主页加载出来的整个进程,所以这时分首屏的优化就显得很重要了,这儿大致说下首屏优化的几个方面:
- 从本地回去缓存数据加载
此方法适宜,主页数据不需求及时更新的情况,我们能够把上一次央求到数据缓存在磁盘或许数据库中,发起的的时分,直接从磁盘中加载,加载结束之后再去央求网络数据,这时分假设数据不一样就改写界面,并从头缓存数据,以待下次运用
- 运用骨架屏
这个适宜需求展示实时性比较高的情况,我们在网络央求的时分,去展示骨架屏,给用户一个数据行将出来的感觉
- 拆分央求接口
- 这种情况适宜,主页展示多模块的数据,且模块之间的依靠性比较弱的情况。
- 我们把每个模块的数据央求都放在子线程去处理,数据照应后在子线程结束相关的数据预处理,然后去主线程烘托,这样就把数据分开来,哪个数据先回来,先去烘托哪个模块
- 当然,有时分我们没必要一次央求一切的模块数据,假设一个模块的数据,不会在第一屏闪现,需求在滑动后才干看到的时分,我们就能够对此模块的数据进行推延央求,用到的时分才去央求烘托
- 推延其他信息配备服务
- 关于用到的第三方服务,我们能够推延几秒,放在烘托结束之后去配备
- 关于有时分主页我们需求去获取晋级信息或许一些其他的配备,也能够放在烘托之后再去央求配备