App 啟動(dòng)時(shí)
一般app分為冷啟動(dòng)和熱啟動(dòng)
- 冷啟動(dòng): app點(diǎn)擊啟動(dòng)前召噩,它的進(jìn)程不在系統(tǒng)里靖秩,需要系統(tǒng)新創(chuàng)建一個(gè)進(jìn)程分配給它啟動(dòng)
- 熱啟動(dòng)娃循,app在冷啟動(dòng)后用戶將app退到后臺(tái)胎围,app的進(jìn)程還在系統(tǒng)中的情況下欲低,用戶重新啟動(dòng)進(jìn)入app的過(guò)程米者,當(dāng)然這個(gè)過(guò)程做的事情非常少
因此一般app啟動(dòng)速度都是指冷啟動(dòng)的優(yōu)化
用戶能感知到啟動(dòng)慢韭畸,其實(shí)都是發(fā)生在主線程上。而主線程慢的原因有很多蔓搞,比如在主線程上執(zhí)行大文件讀寫(xiě)操作胰丁,在渲染周期中執(zhí)行大量計(jì)算等。
app啟動(dòng)時(shí)的過(guò)程(用戶點(diǎn)擊app開(kāi)始喂分,到用戶看到第一個(gè)界面之間的時(shí)間):
- main()函數(shù)執(zhí)行之前;
- main()函數(shù)執(zhí)行之后;
- 首屏渲染完成后锦庸。
main()函數(shù)執(zhí)行之前
在main()函數(shù)執(zhí)行前,系統(tǒng)主要會(huì)做以下幾件事:
- 加載可執(zhí)行文件(app的.o文件的集合)
- 加載動(dòng)態(tài)鏈接庫(kù)蒲祈,進(jìn)行rebase指針調(diào)整和bind符號(hào)綁定
- Objc 運(yùn)行時(shí)的初始處理甘萧,包括Objc相關(guān)類(lèi)的注冊(cè),category注冊(cè)梆掸,selector唯一性檢查
- 初始化扬卷,包括了執(zhí)行 +load()方法,attribute((constructor)) 修飾的函數(shù)的調(diào)用酸钦,創(chuàng)建c++靜態(tài)全局變量
因此在這個(gè)階段怪得,對(duì)于優(yōu)化啟動(dòng)速度如下: - 減少動(dòng)態(tài)庫(kù)加載
- 加少加載啟動(dòng)后不會(huì)去使用的類(lèi)或方法
- +load() 方法里的內(nèi)容可以放到首屏渲染完成后在執(zhí)行,或使用 +initialize() 方法替換掉。
- 控制 C++ 全局變量的數(shù)量
main() 函數(shù)執(zhí)行后:
main() 函數(shù)執(zhí)行后的階段汇恤,是指從main() 函數(shù)執(zhí)行開(kāi)始庞钢,到AppDelegate 的 didFinishLaunchingWithOptions 方法里首屏渲染相關(guān)方法執(zhí)行完成。
首頁(yè)的業(yè)務(wù)代碼都是要在這個(gè)階段(渲染前執(zhí)行) - 首屏初始化所需配置文件的讀寫(xiě)操作
- 首屏列表大數(shù)據(jù)的讀取
- 首批渲染的大量計(jì)算
因此梳理出哪些時(shí)首屏渲染必要的初始化功能因谎,哪些是app啟動(dòng)必要的初始化功能基括,哪些是只需要在對(duì)應(yīng)功能開(kāi)始使用時(shí)才需要初始化的
首屏渲染完成后
首屏渲染后的階段,主要完成的是财岔,非首屏其他業(yè)務(wù)服務(wù)模塊的初始化风皿,監(jiān)聽(tīng)的注冊(cè),配置文件的讀取等匠璧,也就是 didFinishLaunchingWithOptions 作用域內(nèi)執(zhí)行首屏渲染之后所有方法執(zhí)行完成
這個(gè)階段用戶已經(jīng)能夠看到app的首頁(yè)信息
總結(jié)
- main() 函數(shù)開(kāi)始執(zhí)行后渲染完成前只處理首屏相關(guān)的業(yè)務(wù)桐款,其他無(wú)關(guān)的業(yè)務(wù)放在首屏渲染完成后去做
- 在首屏渲染完成前主線程中一個(gè)耗時(shí)的操作滯后或者通過(guò)異步執(zhí)行