一、App啟動時都干了什么事?
一般情況下,App 的啟動分為冷啟動和熱啟動。冷啟動是指app點擊啟動前,進程不在系統(tǒng)里,需要系統(tǒng)新創(chuàng)建一個進程分配給它啟動的過程,是一次完整的啟動;熱啟動則是指app在冷啟動后進入后臺,進程還在系統(tǒng)的情況下,用戶重新啟動app的過程,此過程事情非常少。
用戶能感知的啟動慢,都發(fā)生在主線程上。主線程慢的原因很多,比如在主線程上執(zhí)行了大文件操作、在渲染周期中執(zhí)行大量計算等。
一般來說,app的啟動時間是指用戶點擊app開始到用戶看到第一個界面之間的時間。主要包括三個階段:
1.main() 函數(shù)執(zhí)行前;
2.main() 函數(shù)執(zhí)行后;
3.首屏渲染完成后。
main() 函數(shù)執(zhí)行前,系統(tǒng)主要操作:
加載可執(zhí)行文件(App的.o文件的集合);
加載動態(tài)鏈接庫,進行rebase指針調(diào)整和bind符號綁定;
Objc運行時的初始化處理,包括Objc相關(guān)類的注冊、category注冊、selector唯一性檢查等;
初始化,包括了執(zhí)行+load()方法、attribute((constructor)) 修飾的函數(shù)的調(diào)用、創(chuàng)建C++靜態(tài)全局變量;
相應(yīng)的,此階段對于啟動速度優(yōu)化來說可做的事情包括:
減少動態(tài)庫加載;
減少加載啟動后不會去使用的類或方法;
+load() 方法里的內(nèi)容可以放到首屏渲染完成后再執(zhí)行,或使用 +initialize() 方法替換掉。
控制 C++ 全局變量的數(shù)量。
main()函數(shù)執(zhí)行后的階段,指用戶點擊圖標(biāo)到appDelegate的didFinishLaunchingWithOptions方法里首屏渲染相關(guān)方法執(zhí)行完成。
首頁的業(yè)務(wù)代碼都是在這個階段,即首屏渲染前執(zhí)行的,主要包括:
首屏初始化所需配置文件的讀寫操作;
首屏列表大數(shù)據(jù)的讀??;
首屏渲染的大量計算等;
應(yīng)該從功能上梳理出哪些是首屏渲染必要的初始化功能,哪些是App啟動必要的初始化功能,而哪些是只需要在對應(yīng)功能開始使用時才需要初始化的。
首屏渲染完成后的階段,主要完成的是非首屏其他業(yè)務(wù)服務(wù)模塊的初始化、監(jiān)聽的注冊、配置文件的讀取等;即是從首屏渲染完成到didFinishLaunchingWithOptions方法作用域結(jié)束;
弄清App各階段的任務(wù)后,就可針對性地優(yōu)化。包括功能級別和方法級別的啟動優(yōu)化。