iOS-APP性能優(yōu)化-啟動優(yōu)化

APP的啟動可以分為2種:

  • 冷啟動(Cold Launch):從零開始啟動APP仇矾。
  • 熱啟動(Warm Launch):APP已經(jīng)在內(nèi)存中入热,在后臺存活著拍棕,再次點擊圖標(biāo)啟動APP。
    通常所做的啟動優(yōu)化勺良,都是針對冷啟動做優(yōu)化绰播。

通過添加環(huán)境變量可以打印出APP的啟動時間分析,點擊Edit scheme -> Run -> Arguments尚困,給Environment Variables添加一個DYLD_PRINT_STATISTICS蠢箩,并且把Value設(shè)置為1,如下圖:

Total pre-main time: 825.00 milliseconds (100.0%) //main函數(shù)調(diào)用之前總耗時
         dylib loading time: 407.70 milliseconds (49.4%)//動態(tài)庫加載耗時
        rebase/binding time:  45.62 milliseconds (5.5%)
            ObjC setup time: 100.80 milliseconds (12.2%)//OC結(jié)構(gòu)體準(zhǔn)備耗時
           initializer time: 270.75 milliseconds (32.8%)//初始化耗時
           slowest intializers ://比較慢的加載
             libSystem.B.dylib :   7.66 milliseconds (0.9%)
    libMainThreadChecker.dylib :  29.10 milliseconds (3.5%)
          libglInterpose.dylib :  83.99 milliseconds (10.1%)
         libMTLInterpose.dylib :  38.42 milliseconds (4.6%)
                      xxxxxx : 174.05 milliseconds (21.0%)

如果需要更詳細(xì)的信息事甜,那就將DYLD_PRINT_STATISTICS改為DYLD_PRINT_STATISTICS_DETAILS并且Value也是設(shè)置為1谬泌,打印如下:

  total time: 1.9 seconds (100.0%)//總耗時
  total images loaded:  459 (443 from dyld shared cache)//鏡像加載耗時
  total segments mapped: 49, into 5926 pages with 984 pages pre-fetched
  total images loading time: 1.3 seconds (70.1%)
  total load time in ObjC:  96.78 milliseconds (4.8%)//加載objc
  total debugger pause time: 973.79 milliseconds (48.8%)
  total dtrace DOF registration time:   0.12 milliseconds (0.0%)
  total rebase fixups:  479,455
  total rebase fixups time:  41.04 milliseconds (2.0%)
  total binding fixups: 615,196
  total binding fixups time: 192.49 milliseconds (9.6%)
  total weak binding fixups time:   4.25 milliseconds (0.2%)
  total redo shared cached bindings time: 194.69 milliseconds (9.7%)
  total bindings lazily fixed up: 0 of 0
  total time in initializers and ObjC +load: 259.27 milliseconds (13.0%)
                         libSystem.B.dylib :   8.80 milliseconds (0.4%)
               libBacktraceRecording.dylib :  10.29 milliseconds (0.5%)
                                Foundation :   2.01 milliseconds (0.1%)
                libMainThreadChecker.dylib :  28.12 milliseconds (1.4%)
              libViewDebuggerSupport.dylib :   4.90 milliseconds (0.2%)
                      libglInterpose.dylib :  76.86 milliseconds (3.8%)
                     libMTLInterpose.dylib :  39.89 milliseconds (2.0%)
                              LookinServer :   2.89 milliseconds (0.1%)
                                  xxxxxx : 160.63 milliseconds (8.0%)
total symbol trie searches:    1428216
total symbol table binary searches:    0
total images defining weak symbols:  45
total images using weak symbols:  113

一般總時間在800ms以內(nèi)都是比較正常的,如果大于800ms就可以優(yōu)化了逻谦。

冷啟動的三大階段

APP的冷啟動可以概括為3大階段:

  • dyld

  • runtime

  • main


  • dyld

dyld(dynamic link editor)掌实,它是Apple的動態(tài)鏈接器,可以用來裝載Mach-O文件(可執(zhí)行文件邦马、動態(tài)庫等)贱鼻。

啟動APP時,dyld動態(tài)鏈接器會裝載APP的可執(zhí)行文件滋将,同時會遞歸加載所有依賴的動態(tài)庫邻悬。
右鍵點擊XX.app選擇Show in Finder,找到XX.app随闽,右鍵點擊XX.app選擇顯示包內(nèi)容拘悦,可以發(fā)現(xiàn)里面有個Unix可執(zhí)行文件,平時我們寫的所有代碼都在這里面了橱脸,這就是一個Mach-O格式的可執(zhí)行文件础米。
但是我們項目開發(fā)中也會依賴一些動態(tài)庫,比如UIKit添诉、Foundation屁桑,這些動態(tài)庫都不是包含在可執(zhí)行文件里面的,可執(zhí)行文件里面只有一些依賴信息栏赴,比如這個項目依賴哪些動態(tài)庫蘑斧,一個動態(tài)庫也可能依賴另一個動態(tài)庫。
dyld階段,dyld動態(tài)鏈接器會裝載可執(zhí)行文件竖瘾,以及檢查可執(zhí)行文件依賴哪些動態(tài)庫沟突,并加載那些動態(tài)庫,一個動態(tài)庫也可能依賴另一個動態(tài)庫捕传,dyld動態(tài)鏈接器就是這樣一個一個檢查惠拭,遞歸查找,直到裝載完所有的動態(tài)庫到內(nèi)存中庸论。
當(dāng)dyld把可執(zhí)行文件职辅、動態(tài)庫都裝載完畢后,會通知Runtime進(jìn)行下一步的處理聂示。

  • runtime

啟動APP時域携,runtime所做的事情有:

1.調(diào)用map_images函數(shù)進(jìn)行可執(zhí)行文件內(nèi)容的解析和處理
2.在load_images函數(shù)中調(diào)用call_load_methods,調(diào)用所有ClassCategory+load方法
3.進(jìn)行各種objc結(jié)構(gòu)的初始化(注冊Objc類 鱼喉、初始化類對象等等)
4.調(diào)用C++靜態(tài)初始化器和__attribute__((constructor))修飾的函數(shù)

到此為止秀鞭,可執(zhí)行文件和動態(tài)庫中所有的符號(Class,Protocol扛禽,Selector锋边,IMP,…)都已經(jīng)按格式成功加載到內(nèi)存中旋圆,被runtime 所管理。

  • main

總結(jié)一下
APP的啟動由dyld主導(dǎo)麸恍,將可執(zhí)行文件加載到內(nèi)存灵巧,順便加載所有依賴的動態(tài)庫
并由runtime負(fù)責(zé)加載成objc定義的結(jié)構(gòu)
所有初始化工作結(jié)束后,dyld就會調(diào)用main函數(shù)
接下來就是UIApplicationMain函數(shù)抹沪,AppDelegateapplication:didFinishLaunchingWithOptions:方法

冷啟動優(yōu)化

按照不同的階段:

  • dyld:
    減少動態(tài)庫刻肄、合并一些動態(tài)庫(定期清理不必要的動態(tài)庫)
    減少Objc類、分類的數(shù)量融欧、減少Selector數(shù)量(定期清理不必要的類敏弃、分類)
    減少C++虛函數(shù)數(shù)量 (因為一旦有虛函數(shù)就要多維護(hù)一張?zhí)摫恚刑摫淼脑捓鋯拥臅r候就要多耗費一點時間)
    Swift盡量使用struct (因為加載類的時候也耗費時間)

  • runtime:
    +initialize方法和dispatch_once取代所有的__attribute__((constructor))噪馏、C++靜態(tài)構(gòu)造器麦到、ObjC+load方法。

  • main:
    在不影響用戶體驗的前提下欠肾,盡可能將一些操作延遲瓶颠,不要全部都放在didFinishLaunchingWithOptions方法中,也就是按需加載刺桃。

貼一些啟動優(yōu)化的文檔:
iOS開發(fā)高手課--App 啟動速度怎么做優(yōu)化與監(jiān)控粹淋?
看到這篇啟動優(yōu)化,讓你的App有順滑無比的啟動速度
iOS App冷啟動治理:來自美團(tuán)外賣的實踐

我是如何讓微博綠洲的啟動速度提升30%的

廖威雄: 利用attribute((section()))構(gòu)建初始化函數(shù)表與Linux內(nèi)核init的實現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市桃移,隨后出現(xiàn)的幾起案子屋匕,更是在濱河造成了極大的恐慌,老刑警劉巖借杰,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件过吻,死亡現(xiàn)場離奇詭異,居然都是意外死亡第步,警方通過查閱死者的電腦和手機疮装,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粘都,“玉大人廓推,你說我怎么就攤上這事◆嫠恚” “怎么了樊展?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長堆生。 經(jīng)常有香客問我专缠,道長,這世上最難降的妖魔是什么淑仆? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任涝婉,我火速辦了婚禮,結(jié)果婚禮上蔗怠,老公的妹妹穿的比我還像新娘墩弯。我一直安慰自己,他們只是感情好寞射,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布渔工。 她就那樣靜靜地躺著,像睡著了一般桥温。 火紅的嫁衣襯著肌膚如雪引矩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天侵浸,我揣著相機與錄音旺韭,去河邊找鬼。 笑死掏觉,一個胖子當(dāng)著我的面吹牛茂翔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播履腋,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼珊燎,長吁一口氣:“原來是場噩夢啊……” “哼惭嚣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起悔政,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤晚吞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谋国,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體槽地,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年芦瘾,在試婚紗的時候發(fā)現(xiàn)自己被綠了捌蚊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡近弟,死狀恐怖缅糟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情祷愉,我是刑警寧澤窗宦,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站二鳄,受9級特大地震影響赴涵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜订讼,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一髓窜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧欺殿,春花似錦寄纵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哄陶。三九已至帆阳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屋吨,已是汗流浹背蜒谤。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留至扰,地道東北人鳍徽。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像敢课,于是被迫代替她去往敵國和親阶祭。 傳聞我的和親對象是個殘疾皇子绷杜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容