iOS啟動耗時(shí)分析

????????啟動耗時(shí)分析殊霞,一般我們會以main函數(shù)作為分割點(diǎn),main之前和main之后main之前稱為per-main 階段拿愧。這個(gè)由dyld給你反饋應(yīng)用的耗時(shí)凶伙。main之后由開發(fā)者自己檢測。我們可以從main開始打點(diǎn)苍匆,到第一個(gè)頁面顯示為止刘急。

通過實(shí)際的調(diào)試,我們得到各個(gè)函數(shù)的調(diào)用順序如下:

啟動頁

main()

UIApplicationMain()

willFinishLaunchingWithOptions()

didFinishLaunchingWithOptions()

loadView()

viewDidLoad()

applicationDidBecomeActive()

啟動頁是在main()函數(shù)調(diào)用之前出來的浸踩,main()是程序的入口叔汁,里面調(diào)用了UIApplicationMain()。當(dāng)App從didFinishLaunchingWithOptions()返回的時(shí)候检碗,實(shí)際的UI立刻開始加載据块,但是在applicationDidBecomeActive()這個(gè)回調(diào)完成之前,UI即使已經(jīng)初始化后裸,但仍舊被阻塞著瑰钮。

總的啟動時(shí)間T包括main()調(diào)用之前的pre-main timeT0,

加上從main()到applicationDidBecomeActive()的時(shí)間T1微驶。

pre-main階段耗時(shí)

?main函數(shù)之前的檢測蘋果提供了支持浪谴,具體配置方式如圖

----首先進(jìn)入Edit Scheme

----然后配置的 key 為:DYLD_PRINT_STATISTICS

----然后我們再運(yùn)行項(xiàng)目,該項(xiàng)目 pre-main 的耗時(shí)就會在控制臺輸出因苹。

各階段耗時(shí)分析

dylib loading time 動態(tài)庫載入耗時(shí)

載入動態(tài)庫苟耻,這個(gè)過程中,會去裝載app使用的動態(tài)庫扶檐,而動態(tài)庫之間有它自己的依賴關(guān)系凶杖,所以會消耗時(shí)間去查找和讀取。

優(yōu)化建議:?

1.系統(tǒng)的動態(tài)庫款筑,做了優(yōu)化智蝠。所以從效率的角度來說腾么,盡可能使用系統(tǒng)庫;

2.而對于開發(fā)者定義導(dǎo)入的動態(tài)庫(dynamically linked shared library)杈湾,則需要在花費(fèi)更多的時(shí)間解虱。Apple官方建議盡量少的使用自定義的動態(tài)庫,或者考慮合并多個(gè)動態(tài)庫漆撞,其中一個(gè)建議是當(dāng)大于6個(gè)的時(shí)候殴泰,則需要考慮合并它們;

3.在性能上出發(fā)將動態(tài)庫編譯成靜態(tài)庫也會優(yōu)化這部分時(shí)間浮驳;

rebase/binding time 修正符號和綁定符號耗時(shí)

Rebase:在鏡像(MachO文件)內(nèi)部調(diào)整指針的指向悍汛,針對mach-o在加載到內(nèi)存中不是固定的首地址(ASLR)這一現(xiàn)象做數(shù)據(jù)修正的過程。

iOS4.3后引入了 ASLR 至会,MachO會被加載到隨機(jī)地址离咐,這個(gè)隨機(jī)的地址跟代碼和數(shù)據(jù)指向的舊地址會有偏差。dyld 需要修正這個(gè)偏差奋献,做法就是將 dylib 內(nèi)部的指針地址都加上這個(gè)偏移量健霹。

binding:將指針指向鏡像(MachO文件)外部的內(nèi)容旺上,binding就是將這個(gè)二進(jìn)制調(diào)用的外部符號進(jìn)行綁定的過程瓶蚂。

優(yōu)化建議:

1.核心思想是在進(jìn)行動態(tài)庫的重定位和綁定(Rebase/binding)過程中減少指針修正;

2.減少Objective-C類數(shù)量宣吱,減少分類窃这,減少實(shí)例變量和函數(shù)(刪除不用的類以及冗余代碼,再深一點(diǎn)就是減少第三方工具的使用征候,可以查看源碼杭攻,自己實(shí)現(xiàn));

3.減少C++虛函數(shù)疤坝;

4.多使用Swift結(jié)構(gòu)體(推薦使用swift)

ObjC setup time OC類注冊的耗時(shí)

主要做以下幾件事來完成Objc Setup:

1兆解、讀取二進(jìn)制文件的 DATA 段內(nèi)容,找到與 objc 相關(guān)的信息

2跑揉、注冊 Objc 類锅睛,ObjC Runtime 需要維護(hù)一張映射類名與類的全局表。當(dāng)加載一個(gè) MachO 時(shí)历谍,它定義的所有的類都需要被注冊到這個(gè)全局表中现拒;

3、讀取 protocol 以及 category 的信息望侈,把category的定義插入方法列表 (category registration)印蔬,

優(yōu)化建議:

1.不刻意的去減少幾個(gè)類,但是可以避免浪費(fèi)脱衙;

2 隨著項(xiàng)目的不斷迭代侥猬,很多模塊和方法已經(jīng)被廢棄但是卻一直留存在項(xiàng)目中例驹,導(dǎo)致項(xiàng)目越來越臃腫;

3.我們可以使用一些工具來查找項(xiàng)目中沒有被用到的文件退唠。從而達(dá)到優(yōu)化眠饮;

initializer time?其他初始化,如上圖铜邮,細(xì)分為其他的幾個(gè)部分

1仪召、Objc的+load()函數(shù)

2、C++的構(gòu)造函數(shù)屬性函數(shù) 形如attribute((constructor)) void DoSomeInitializationWork()

優(yōu)化建議:?

1.我們能做的就是將不必須在+load方法中做的事情延遲到+initialize中松蒜;

2.這是因?yàn)?load方法是在app啟動的時(shí)候就被調(diào)用扔茅,而+initialize方法則是在Class第一次使用的時(shí)候才調(diào)用,相當(dāng)于是懶加載了秸苗≌倌龋可以把+load中的代碼移到initialize中,并結(jié)合dispatch_once來防止重復(fù)調(diào)用惊楼;

3.但是我們項(xiàng)目中只有在使用method swizzling的時(shí)候會在+load中調(diào)用方法玖瘸。所以這一點(diǎn)也沒什么好優(yōu)化的;

pre-main階段耗時(shí)總結(jié):

1. 動態(tài)庫加載越多檀咙,啟動越慢

2. ObjC類雅倒,方法越多,啟動越慢

3. ObjC的+load越多弧可,啟動越慢

4. C的constructor函數(shù)越多蔑匣,啟動越慢

5. C++靜態(tài)對象越多,啟動越慢

main()到applicationDidBecomeActive()的階段耗時(shí)

我們可以使用Xcode自帶工具Instruments里面的Time Profiler來獲取棕诵,也可以在main()的第一句和applicationDidBecomeActive()的最后一句加上獲取時(shí)間的代碼CFAbsoluteTimeGetCurrent()裁良,

Time Profiler

工具通過Xcode工具欄中Product->Profile(command+i)可以啟動,(也可以通過Xcode->Open Developer Tool->Instruments)啟動后界面如下:

選擇Time Profiler,打開后如圖:

點(diǎn)擊左上角紅色按鈕運(yùn)行校套,勾選左下角Call Tree中Separate Thread和Hide System Libraries价脾,等到第一個(gè)頁面顯示出來的之后,點(diǎn)擊左上角暫停按鈕笛匙,下面就會統(tǒng)計(jì)出每個(gè)步驟的耗時(shí)情況侨把。這個(gè)時(shí)候我們就可以很容易得到啟動時(shí)間T1。

針對這塊時(shí)間的耗時(shí)優(yōu)化總結(jié):

我們通過Time Profiler拿到每個(gè)步驟的耗時(shí)之后膳算,右下角的 Heaviest Trace 可查看比較消耗CPU的代碼座硕,雙擊點(diǎn)擊進(jìn)去可查看到對應(yīng)的代碼,進(jìn)行修改涕蜂。有些操作可以延后執(zhí)行华匾,或者異步執(zhí)行等,這些需要根據(jù)自己的業(yè)務(wù)邏輯在處理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蜘拉,一起剝皮案震驚了整個(gè)濱河市萨西,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旭旭,老刑警劉巖谎脯,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異持寄,居然都是意外死亡源梭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門稍味,熙熙樓的掌柜王于貴愁眉苦臉地迎上來废麻,“玉大人,你說我怎么就攤上這事模庐≈蚶ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵掂碱,是天一觀的道長怜姿。 經(jīng)常有香客問我,道長疼燥,這世上最難降的妖魔是什么沧卢? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮悴了,結(jié)果婚禮上搏恤,老公的妹妹穿的比我還像新娘违寿。我一直安慰自己湃交,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布藤巢。 她就那樣靜靜地躺著搞莺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掂咒。 梳的紋絲不亂的頭發(fā)上才沧,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音绍刮,去河邊找鬼温圆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛孩革,可吹牛的內(nèi)容都是我干的岁歉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼膝蜈,長吁一口氣:“原來是場噩夢啊……” “哼锅移!你這毒婦竟也來了熔掺?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤非剃,失蹤者是張志新(化名)和其女友劉穎置逻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體备绽,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡券坞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肺素。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片报慕。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖压怠,靈堂內(nèi)的尸體忽然破棺而出眠冈,到底是詐尸還是另有隱情,我是刑警寧澤菌瘫,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布蜗顽,位于F島的核電站,受9級特大地震影響雨让,放射性物質(zhì)發(fā)生泄漏雇盖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一栖忠、第九天 我趴在偏房一處隱蔽的房頂上張望崔挖。 院中可真熱鬧,春花似錦庵寞、人聲如沸狸相。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脓鹃。三九已至,卻和暖如春古沥,著一層夾襖步出監(jiān)牢的瞬間瘸右,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工岩齿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留太颤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓盹沈,卻偏偏與公主長得像龄章,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

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

  • 轉(zhuǎn)載自騰訊云 App啟動過程 解析Info.plist加載相關(guān)信息瓦堵,例如如閃屏沙箱建立基协、權(quán)限檢查 Mach-O加載...
    乂濫好人閱讀 982評論 0 0
  • 多作者合集,非商業(yè)行為菇用,為自己學(xué)習(xí)鞏固澜驮。特此聲明 啟動APP的時(shí)候就會花費(fèi)較長的時(shí)間,用戶體驗(yàn)很不好惋鸥。所以針對AP...
    紅色海_閱讀 711評論 0 2
  • 一款 App 的啟動速度杂穷,不單單是用戶體驗(yàn)的事情,往往還決定了它能否獲取更多的用戶卦绣。這就好像陌生人第一次碰面耐量,第一...
    vicentwyh閱讀 1,395評論 0 10
  • 黑色的海島上懸著一輪又大又圓的明月廊蜒,毫不嫌棄地把溫柔的月色照在這寸草不生的小島上。一個(gè)少年白衣白發(fā)溅漾,悠閑自如地倚坐...
    小水Vivian閱讀 3,106評論 1 5
  • 漸變的面目拼圖要我怎么拼? 我是疲乏了還是投降了暮胧? 不是不允許自己墜落锐借, 我沒有滴水不進(jìn)的保護(hù)膜。 就是害怕變得面...
    悶熱當(dāng)乘涼閱讀 4,244評論 0 13