冷啟動(dòng):在APP點(diǎn)擊啟動(dòng)前,他的進(jìn)程不在系統(tǒng)中,需要系統(tǒng)新創(chuàng)建一個(gè)進(jìn)程分配給它啟動(dòng)的情況。冷啟動(dòng)是一次完整的啟動(dòng)過(guò)程。
APP的啟動(dòng)時(shí)間,是指從用戶點(diǎn)擊APP開(kāi)始,到用戶看到第一個(gè)界面之間的時(shí)間。總的來(lái)說(shuō),APP啟動(dòng)主要包括三個(gè)階段:
1.main()函數(shù)執(zhí)行前:pre-main
2.main()函數(shù)執(zhí)行
3.首屏渲染完成
pre-main階段:
?- 加載可執(zhí)行文件(App的.o文件集合)
-?加載動(dòng)態(tài)鏈接庫(kù),進(jìn)行rebase指針調(diào)整和bind符號(hào)綁定
-?Objc運(yùn)行時(shí)的初始處理,包括Objc相關(guān)類注冊(cè)、category注冊(cè)、selector唯一性檢查等
-?初始化,包括了執(zhí)行+load()方法、attribute((constructor))修飾的函數(shù)的調(diào)用、創(chuàng)建C++靜態(tài)全局變量。
相應(yīng)的,這個(gè)階段對(duì)于啟動(dòng)優(yōu)化來(lái)說(shuō),可以做的事情包括:
1.減少動(dòng)態(tài)庫(kù)的加載。每個(gè)庫(kù)本身都有依賴關(guān)系,蘋(píng)果公司建議使用更少的動(dòng)態(tài)庫(kù),并且建議在動(dòng)態(tài)庫(kù)使用的數(shù)量較多時(shí),盡量將多個(gè)動(dòng)態(tài)庫(kù)合并。數(shù)量上,蘋(píng)果公司最多可以支持6個(gè)非系統(tǒng)動(dòng)態(tài)庫(kù)合并為一個(gè)。
2.減少加載啟動(dòng)后不會(huì)去使用的類或者方法。
3.+load()方法里的內(nèi)容可以放到首屏渲染渲染完成后再執(zhí)行,或使用+initialize()方法替換掉。因?yàn)?,在一個(gè)+load()方法里,進(jìn)行運(yùn)行時(shí)方法替換操作會(huì)帶來(lái)4毫秒的消耗。不要小看這4毫秒,積少成多,執(zhí)行+load()方法對(duì)啟動(dòng)速度的影響會(huì)越來(lái)越大。
4.控制C++全局變量的數(shù)量。
5.清除廢棄無(wú)用的代碼和廢棄無(wú)用資源文件。
main()函數(shù)執(zhí)行
-?首屏初始化所需配置文件的讀寫(xiě)操作
-?首屏列表大數(shù)據(jù)的讀取
-?首屏渲染的大量計(jì)算
很多時(shí)候,開(kāi)發(fā)者會(huì)把各種初始化工作都放到這個(gè)階段執(zhí)行,導(dǎo)致渲染完成滯后。更加優(yōu)化的開(kāi)發(fā)方式,應(yīng)該是從功能上梳理出哪些是首屏渲染必要的初始化功能,哪些是APP啟動(dòng)必要的初始化功能,而哪些是只需要在對(duì)應(yīng)功能開(kāi)始使用時(shí)才需要初始化的。梳理完成滯后,將這些初始化功能分別放到合適的階段進(jìn)行。
首屏渲染完成
首屏渲染后的這個(gè)階段,主要完成的是,非首屏其他業(yè)務(wù)服務(wù)模塊的初始化、監(jiān)聽(tīng)的注冊(cè)、配置文件的讀取等。從函數(shù)上來(lái)看,這個(gè)階段指的就是截止到didFinishLaunchingWithOptions方法作用域執(zhí)行結(jié)束。
這個(gè)階段用戶已經(jīng)能夠看到APP的首頁(yè)信息了,所以優(yōu)化的優(yōu)先級(jí)排在最后。但是,那些會(huì)卡住主線程的方法還是要優(yōu)先處理。