前言
什么情況下要去做啟動(dòng)優(yōu)化但狭?
APP啟動(dòng)優(yōu)化,一般指的是冷啟動(dòng)呈队,因?yàn)槔鋯?dòng)過程中要做的事情有點(diǎn)多息罗。但是什么情況下才要去做這個(gè)優(yōu)化才沧?比如啟動(dòng)時(shí)間是多少的情況下才算是時(shí)間過長了温圆?
蘋果建議的是400ms以內(nèi)。如果啟動(dòng)時(shí)間超過20s得运,還會(huì)被系統(tǒng)強(qiáng)殺掉(感覺用戶等待5s都算很長了??)。
另外對(duì)于用戶來說熔掺,從點(diǎn)擊圖標(biāo)到app首頁出現(xiàn)在屏幕上才算是啟動(dòng)完成,因此要評(píng)估從點(diǎn)擊圖標(biāo)到首頁呈現(xiàn)整個(gè)階段的時(shí)間推沸。
怎么取檢測冷啟動(dòng)時(shí)間鬓催?
以APP的進(jìn)程創(chuàng)建時(shí)間作為冷啟動(dòng)的起始時(shí)間
+ (BOOL)processInfoForPID:(int)pid procInfo:(struct kinfo_proc*)procInfo
{
int cmd[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
size_t size = sizeof(*procInfo);
return sysctl(cmd, sizeof(cmd)/sizeof(*cmd), procInfo, &size, NULL, 0) == 0;
}
+ (NSTimeInterval)processStartTime
{
struct kinfo_proc kProcInfo;
if ([self processInfoForPID:[[NSProcessInfo processInfo] processIdentifier] procInfo:&kProcInfo]) {
return kProcInfo.kp_proc.p_un.__p_starttime.tv_sec * 1000.0 + kProcInfo.kp_proc.p_un.__p_starttime.tv_usec / 1000.0;
} else {
NSAssert(NO, @"無法取得進(jìn)程的信息");
return 0;
}
}
分析耗時(shí)位置
APP從點(diǎn)擊圖標(biāo)到首頁展示主要有以下階段:
加載動(dòng)態(tài)庫宇驾,進(jìn)行rebase和bind操作
dyld從主程序文件的header中獲取到需要加載哪些動(dòng)態(tài)庫猴伶,然后去尋找加載。
這一步對(duì)于系統(tǒng)的動(dòng)態(tài)庫布卡,系統(tǒng)做了緩存機(jī)制雇盖,耗時(shí)其實(shí)比較少(如果其他應(yīng)用加載過的話)。
但是對(duì)于我們的embed framework贸街,要依次的進(jìn)行簽名校驗(yàn)薛匪,加載脓鹃。
動(dòng)態(tài)庫加載后,還要依次進(jìn)行rebase和bind操作來修正指針娇跟。
因此個(gè)人覺得太颤,如果內(nèi)嵌的動(dòng)態(tài)庫比較多的話,可以考慮使用靜態(tài)庫吃谣。靜態(tài)庫在編譯的時(shí)候就已經(jīng)link進(jìn)入app的可執(zhí)行文件里,運(yùn)行期間不需要再動(dòng)態(tài)加載
objc setup 和 initializers
- 注冊(cè)objc類岗憋,綁定category到對(duì)應(yīng)的類仔戈,插入方法,屬性等操作悍缠。
- 調(diào)用類的+load函數(shù)
- c++的構(gòu)造函數(shù)
- 非基本類型c++靜態(tài)全局變量的創(chuàng)建
從上面兩步看耐量,如果類越多,+load方法實(shí)現(xiàn)越多趴拧,c++構(gòu)造函數(shù)越多山叮,c++靜態(tài)對(duì)象越多,啟動(dòng)就會(huì)越慢脑又。因此要經(jīng)常刪除無用的類和方法以及盡量減少在+load方法里做操作
接下來就是main函數(shù)之后锐借。
didFinish……
這個(gè)代理方法里钞翔,盡量減少一些操作,或者一些不必要的操作延后處理哮笆。
參考地址:https://tech.meituan.com/2018/12/06/waimai-ios-optimizing-startup.html