App 啟動(dòng)動(dòng)干了那些事情
- 一般情況下app 啟動(dòng)分為冷啟動(dòng)和熱啟動(dòng)
** 冷啟動(dòng)是指,App點(diǎn)擊啟動(dòng)前,他的進(jìn)程不在系統(tǒng)里面,需要?jiǎng)?chuàng)建一個(gè)進(jìn)程分配他的啟動(dòng)情況,這是一次完整的啟動(dòng)過程。
** 熱啟動(dòng)是指,App 在冷啟動(dòng)用戶將app退到后臺(tái),在app 的進(jìn)程還在系統(tǒng)的情況下,用戶點(diǎn)擊log進(jìn)入app的過程,這個(gè)過程做的事情非常少。
用戶能感知到啟動(dòng)慢,其實(shí)都是發(fā)生在主線程上。而主線程慢的原因有很多,比如在主線程中進(jìn)行了大量的讀寫操作、在渲染周期中執(zhí)行了大量的計(jì)算等。
究竟如何才能把a(bǔ)pp啟動(dòng)的所有耗時(shí)都找出來呢?解決這個(gè)問題,你首先要弄清楚App在啟動(dòng)前都做了那些事情能。
一般而言,App的啟動(dòng)時(shí)間,是指涌入點(diǎn)擊App開始,到用戶看到第一個(gè)界面之間的時(shí)間。app 的啟動(dòng)包括三個(gè)階段:
1 main()函數(shù)執(zhí)行前
2 main()函數(shù)執(zhí)行后
3 首屏渲染完成后
main() 函數(shù)執(zhí)行前
在main函數(shù)執(zhí)行前會(huì)做:
- 加載可執(zhí)行的文件
- 加載動(dòng)態(tài)鏈接哭,進(jìn)行rebase 指針調(diào)整和符號(hào)bind
- Objc 運(yùn)行時(shí)處理,包括Objc 相關(guān)類的注冊(cè)、category注冊(cè)、selector 唯一性檢查等。
相應(yīng)的,這個(gè)階段對(duì)于啟動(dòng)優(yōu)化來說,可以做的事情包括 - 減少動(dòng)態(tài)庫的加載。每個(gè)庫本身有依賴關(guān)系,蘋果建議使用更少的動(dòng)態(tài)庫,并且建議在使用動(dòng)態(tài)庫的數(shù)量較多時(shí),盡量將多個(gè)動(dòng)態(tài)庫合并。數(shù)量上,蘋果可以支持6個(gè)非系統(tǒng)動(dòng)態(tài)庫合成一個(gè)
- 減少加載啟動(dòng)后不會(huì)去使用的的類和方法
- +(load)方法里的內(nèi)容可以放到首屏渲染后去完成,或是用+initalize()方法替換。因?yàn)橐粋€(gè)load 方法會(huì)帶來4毫秒的耗時(shí)。
- 控制c++ 全局變量的數(shù)量
mian()函數(shù)后
main()函數(shù)執(zhí)行后的階段,是指從main 函數(shù)執(zhí)行開始,到appDelegate 的didFinishLaunchingWithOptions方法里首頁離屏渲染的相關(guān)執(zhí)行方法執(zhí)行完成。
首頁的業(yè)務(wù)代碼都是在這個(gè)階段,也就是首頁離屏渲染前執(zhí)行包括:
- 首頁初始化需要配置文件的讀寫操作
- 首頁列表大數(shù)據(jù)的讀取
- 首頁渲染的大量計(jì)算
很多時(shí)候,開發(fā)者會(huì)把各種初始化工作都放到這個(gè)階段執(zhí)行,導(dǎo)致渲染完成滯后。更加優(yōu)化的開發(fā)方式,應(yīng)該是從功能上梳理那些是首屏渲染必要的初始化,那些是app 啟動(dòng)必要的初始化功能,而那些是功能需要使用的時(shí)候才需要的。