一荣病、背景
隨著業(yè)務(wù)代碼的快速迭代码撰,項(xiàng)目越來(lái)越大,啟動(dòng)時(shí)間越來(lái)越慢个盆,用戶(hù)體驗(yàn)不好脖岛,就可能卸載APP,失去流量颊亮。所以冷啟動(dòng)時(shí)間不容忽視柴梆。
二、定義
一般把冷啟動(dòng)分為pre-main 和main兩個(gè)階段终惑,但是也有分為三個(gè)階段的绍在,第三階段是didFinishLaunchingWithOptions 到首頁(yè)渲染完,我個(gè)人也是傾向于三個(gè)階段狠鸳。
階段一:pre-main
- 裝載APP的可執(zhí)行文件
- 遞歸加載所有依賴(lài)的動(dòng)態(tài)庫(kù)
- 調(diào)用map_images進(jìn)行可執(zhí)行文件內(nèi)容的解析和處理
- 在load_images中調(diào)用call_load_methods,調(diào)用所有的Class和Category的 + load方法
- 進(jìn)行各種objc結(jié)構(gòu)初始化(注冊(cè)O(shè)bjec類(lèi)揣苏、初始化類(lèi)對(duì)象等等)
- 調(diào)用C++ 靜態(tài)初始化器和 _attribute_((constructor))修飾函數(shù)
階段二:main
- main()
- UIApplicationMain()
- AppDelegate的application: didFinishLaunchingWithOptions:方法
階段三:首頁(yè)渲染
- 相關(guān)業(yè)務(wù)組件初始化
- 基礎(chǔ)信息數(shù)據(jù)同步,首頁(yè)數(shù)據(jù)請(qǐng)求
- 廣告件舵,彈層卸察,一些第三方業(yè)務(wù),等
- ......
三铅祸、常用的檢測(cè)工具
- Xcode:(Edit scheme -> Run -> Arguments DYLD_PRINT_STATISTICS設(shè)置為1,如果需要更詳細(xì)的信息坑质,那就將DYLD_PRINT_STATISTICS_DETAILS設(shè)置為1)
total time: 4.3 seconds (100.0%)
total images loaded: 529 (496 from dyld shared cache)
total segments mapped: 122, into 52321 pages
total images loading time: 1.9 seconds (46.2%)
total load time in ObjC: 456.16 milliseconds (10.6%)
total debugger pause time: 1.2 seconds (29.1%)
total dtrace DOF registration time: 0.00 milliseconds (0.0%)
total rebase fixups: 2,187,197
total rebase fixups time: 235.26 milliseconds (5.4%)
total binding fixups: 832,686
total binding fixups time: 712.43 milliseconds (16.5%)
total weak binding fixups time: 7.12 milliseconds (0.1%)
total redo shared cached bindings time: 722.42 milliseconds (16.7%)
total bindings lazily fixed up: 0 of 0
total time in initializers and ObjC +load: 901.40 milliseconds (20.9%)
libSystem.B.dylib : 12.16 milliseconds (0.2%)
libBacktraceRecording.dylib : 18.14 milliseconds (0.4%)
libobjc.A.dylib : 4.39 milliseconds (0.1%)
libglInterpose.dylib : 368.62 milliseconds (8.5%)
libMTLCapture.dylib : 12.47 milliseconds (0.2%)
libViewDebuggerSupport.dylib : 9.48 milliseconds (0.2%)
AliRTCSdk : 19.62 milliseconds (0.4%)
AliyunPlayer : 5.93 milliseconds (0.1%)
AliyunVideoSDKPro : 4.72 milliseconds (0.1%)
BAFNetwork : 45.54 milliseconds (1.0%)
NMC : 10.16 milliseconds (0.2%)
DXRiskWithIDFA : 32.36 milliseconds (0.7%)
Demo : 659.64 milliseconds (15.3%)
total symbol trie searches: 1679888
total symbol table binary searches: 0
total images defining weak symbols: 68
total images using weak symbols: 143
-
Time Profiler :
image.png
四合武、策略
冷啟動(dòng)優(yōu)化工作不是一朝一夕的事,特別是大項(xiàng)目不但需要團(tuán)隊(duì)協(xié)作涡扼,而且優(yōu)化周期長(zhǎng)稼跳。根據(jù)執(zhí)行階段大致可以從以下幾點(diǎn)排查,但是具體優(yōu)化方案還得根據(jù)自己項(xiàng)目的一個(gè)實(shí)際情況來(lái)制定
pre-main
1吃沪、減少動(dòng)態(tài)庫(kù)汤善、合并一些動(dòng)態(tài)庫(kù)(定期清理不必要的動(dòng)態(tài)庫(kù))
2、減少Objc類(lèi)票彪、分類(lèi)的數(shù)量红淡、減少Selector數(shù)量(定期清理不必要的類(lèi)、分類(lèi))
3降铸、減少C++虛函數(shù)數(shù)量
4在旱、Swift盡量使用struct
5、用+initialize方法和dispatch_once取代所有的_attribute_((constructor))推掸、C++靜態(tài)構(gòu)造器桶蝎、Objc的+loadmain
1、在不影響用戶(hù)體驗(yàn)的前提下谅畅,盡可能將一些操作延遲登渣,不要全部都放在didFinishLaunching方法中
2、監(jiān)控铃彰、埋點(diǎn)绍豁、基礎(chǔ)功能設(shè)置 在willFinishLaunching
3芯咧、定位牙捉、網(wǎng)絡(luò)配置、基礎(chǔ)SDK 敬飒、必須的數(shù)據(jù) 在 didFinishLaunching首頁(yè)渲染
1邪铲、避免使用xib
2、首頁(yè)一般關(guān)聯(lián)業(yè)務(wù)較多无拗,優(yōu)先請(qǐng)求和渲染用戶(hù)可見(jiàn)的頁(yè)面
3带到、業(yè)務(wù)組件,業(yè)務(wù)相關(guān)配置等英染,在首頁(yè)渲染完成之后