iOS 的 App 啟動時長大概可以這樣計算:
- t(
App 總啟動時間) = t1(main 調用之前的加載時間) + t2(main 調用之后的加載時間) - t1 =
系統(tǒng) dylib(動態(tài)鏈接庫)和自身 App 可執(zhí)行文件的加載 - t2 =
main方法執(zhí)行之后到AppDelegate類中的application:didFinishLaunchingWithOptions:方法執(zhí)行結束前這段時間,主要是構建第一個界面,并完成渲染展示
- 在
t1階段加快App啟動的建議:
- 盡量使用靜態(tài)庫,減少動態(tài)庫的使用,動態(tài)鏈接比較耗時,如果要用動態(tài)庫,盡量將多個
dylib動態(tài)庫合并成一個 - 盡量避免對系統(tǒng)庫使用
optional linking,如果App用到的系統(tǒng)庫在你所有支持的系統(tǒng)版本上都有,就設置為required,因為optional會有些額外的檢查 - 減少
Objective-C Class、Selector、Category的數量,可以合并或者刪減一些OC類 - 刪減一些無用的靜態(tài)變量,刪減沒有被調用到或者已經廢棄的方法
- 將不必須在
+load中做的事情盡量挪到+initialize中,+initialize是在第一次初始化這個類之前被調用,+load在加載類的時候就被調用。盡量將+load里的代碼延后調用 - 盡量不要用
C++虛函數,創(chuàng)建虛函數表有開銷 - 不要使用
__attribute__((constructor))將方法顯式標記為初始化器,而是讓初始化方法調用時才執(zhí)行。比如使用dispatch_once(),pthread_once()或 std::once() - 在初始化方法中不調用
dlopen(),dlopen()有性能和死鎖的可能性 - 在初始化方法中不創(chuàng)建線程
- 在
t2階段加快App啟動的建議:
- 盡量不要使用
xib/storyboard,而是用純代碼作為首頁UI,如果要用xib/storyboard,不要在xib/storyboard中存放太多的視圖 - 對
application:didFinishLaunchingWithOptions:里的任務盡量延遲加載或懶加載 - 不要在
NSUserDefaults中存放太多的數據,NSUserDefaults是一個plist文件,plist文件會被反序列化一次 - 避免在啟動時打印過多的
log,少用NSLog,因為每一次NSLog的調用都會創(chuàng)建一個新的NSCalendar實例 - 為了防止使用
GCD創(chuàng)建過多的線程,解決方法是創(chuàng)建串行隊列,或者使用帶有最大并發(fā)數限制的NSOperationQueue - 不要在主線程執(zhí)行
磁盤、網絡、Lock或者dispatch_sync、發(fā)送消息給其他線程等操作