繼APP啟動時間測量後,接下來要做APP啟動時間優化,這一部份開發者能夠干涉嗎?其實是可以的!
我們可以分兩部分優化如上圖,pre-main time和loading time。
一、APP啟動過程
1.解析Info.plist
- 加載相關信息,例如如閃屏
- 沙箱建立、權限檢查
2.Mach-O加載
- 如果是胖二進製文件,尋找合適當前CPU類別的部分
- 加載所有依賴的Mach-O文件(遞歸調用Mach-O加載的方法)
- 定位內部、外部指針引用,例如字符串、函數等
- 執行聲明為__attribute__((constructor))的C函數
- 加載類擴展(Category)中的方法
- C++靜態對象加載、調用ObjC的+load 函數
3.程序執行
- 調用main()
- 調用UIApplicationMain()
- 調用applicationWillFinishLaunching
二、影響APP啟動性能的因素
1. main()
函數之前耗時的影響因素
- 動態庫加載越多,啟動越慢。
- ObjC類越多,啟動越慢
- C的
constructor
函數越多,啟動越慢 - C++靜態對象越多,啟動越慢
- ObjC的
+load
越多,啟動越慢
實驗證明,在ObjC類的數目一樣多的情況下,需要加載的動態庫越多,App啟動就越慢。同樣的,在動態庫一樣多的情況下,ObjC的類越多,App的啟動也越慢。需要加載的動態庫從1個上升到10個的時候,用戶幾乎感知不到任何分別,但從10個上升到100個的時候就會變得十分明顯。同理,100個類和1000個類,可能也很難查察覺得出,但1000個類和10000個類的分別就開始明顯起來。
優化Dylib Loading前
優化Dylib Loading後
同樣的,盡量不要寫__attribute__((constructor))
的C函數,也盡量不要用到C++的靜態對象;至於ObjC的+load
方法,似乎大家已經習慣不用它了。任何情況下,能用dispatch_once()
來完成的,就盡量不要用到以上的方法。
優化Rebase/Binding前
優化Rebase/Binding後
2. main()
函數之後耗時的影響因素
從main()
函數開始至didFinishLaunchingWithOptions
結束,我們統一稱為main()
函數之後的部分。
- 執行
main()
函數的耗時 - 執行
didFinishLaunchingWithOptions
的耗時 rootViewController
及其childViewController
的加載、view
及其subviews
的加載
3. didFinishLaunchingWithOptions
的耗時
其實didFinishLaunchingWithOptions
方法裡我們一般都有以下的邏輯:
- 初始化第三方SDK
- 配置APP運行需要的環境,比如
rootViewController
加載 - 自己的一些工具類的初始化
三、制定優化目標
分為四個部分:
main()
函數之前main()
函數之後至didFinishLaunchingWithOptions
完成- App完成所有本地數據的加載並將相應的信息展示給用戶
- App完成所有聯網數據的加載並將相應的信息展示給用戶
四、優化方案
1. main()
函數之前的優化
- 移除不需要用到的動態庫。
- 移除不需要用到的類。
- 合併功能類似的類和擴展(Category)。
- 壓縮資源圖片。
- 減少load 方法中執行的代碼。
2. main()
函數之後至didFinishLaunchingWithOptions
完成的優化
這一步主要優化didFinishLaunchingWithOptions
方法中的代碼和rootViewController
加載的優化。
didFinishLaunchingWithOptions
優化
對於didFinishLaunchingWithOptions
,這裡面的初始化是必須執行的,但是我們可以適當的根據功能的不同對應的適當延遲啟動的時機。對於我們項目,我將初始化分為三個類型:
- 日誌、統計等必須在APP 一起動就最先配置的事件
- 項目配置、環境配置、用戶訊息的初始化、推送、IM等事件
- 其他SDK 和配置事件
對於第一類,由於這類事件的特殊性,所以必須第一時間啟動,仍然把它留在didFinishLaunchingWithOptions
裡啟動。第二類事件,這些功能在用戶進入APP主體的之前是必須要加載完的,所以我們可以把它放在第二批,也就是用戶已經看到廣告頁面,再進行廣告倒計時的時候再啟動。第三類事件,由於不是必須的,所以我們可以放在第一個界面渲染完成以後的viewDidAppear
方法裡,這裡完全不會影響到啟動時間。
rootViewController
加載優化
這個只能看具體的邏輯和業務了,盡量把不必要的業務邏輯和網絡請求等延後加載。
—
以上是對岸朋友精心翻譯並詮釋WWDC 2016 406 Optimizing App Startup Time課程,講到底層我就頭痛,只要做工具的高手能處理好,我便能安心發揮創造力來開發App,若真有需要的話就可以來做啟動優化~
Comments on: "[iOS] APP啟動時間優化" (1)
[…] 接下來我們來研究如何優化App啟動時間吧:)~ […]
讚讚