APP的啓動能夠分爲2種
- 冷啓動(Cold Launch):從零開始啓動APP;
- 熱啓動(Warm Launch):APP已經在內存中,在後臺存活着,再次點擊圖標啓動APP。
APP啓動時間的優化,主要是針對冷啓動進行優化
- 經過添加環境變量能夠打印出APP的啓動時間分析(Edit scheme -> Run -> Arguments) DYLD_PRINT_STATISTICS設置爲1;
- 若是須要更詳細的信息,那就將DYLD_PRINT_STATISTICS_DETAILS設置爲1。
APP的冷啓動能夠歸納爲3大階段
- dyld(dynamic link editor):
- Apple的動態連接器,能夠用來裝載Mach-O文件(可執行文件、動態庫等)
- runtime;
- main。
1. dyld 階段:
- 裝載APP的可執行(Mach-o)文件,同時會遞歸加載全部依賴的動態庫;
- 當dyld把可執行文件、動態庫都裝載完畢後,會通知Runtime進行下一步的處理。
2. runtime 階段:
- 調用
map_images
進行可執行文件內容的解析和處理:
_dyld_objc_notify_register(&map_images, load_images, unmap_image);
複製代碼
- 在
load_images
中調用call_load_methods
,調用全部Class和Category的+load方法;
// Call +load methods (without runtimeLock - re-entrant)
call_load_methods();
複製代碼
- 進行各類objc結構的初始化(註冊Objc類 、初始化類對象等等)
- 調用C++靜態初始化器和
__attribute__((constructor))
修飾的函數
- 到此爲止,可執行文件和動態庫中全部的符號(Class,Protocol,Selector,IMP,…)都已經按格式成功加載到內存中,被runtime 所管理。
3. main函數啓動階段
- 全部初始化工做結束後,dyld就會調用main函數;
- 接下來就是UIApplicationMain函數,AppDelegate的
application:didFinishLaunchingWithOptions:
方法
冷啓動優化:
1. dyld階段
- 減小動態庫、合併一些動態庫(按期清理沒必要要的動態庫);
- 減小Objc類、分類的數量、減小Selector數量(按期清理沒必要要的類、分類);
- 減小C++虛函數數量;(虛函數的存在,會生成一張虛表)
- Swift儘可能使用struct。
2. runtime階段
- 用+initialize方法和dispatch_once取代全部的
__attribute__((constructor))
、C++靜態構造器、ObjC的+load
。
+ (void)initialize {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
});
}
複製代碼
3. main
- 在不影響用戶體驗的前提下,儘量將一些操做延遲,不要所有都放在finishLaunching方法中;
- 按需加載。
iOS性能優化: