iOS App啟動優(yōu)化(一)—— 了解App的啟動流程

前言:
最近帽馋,小編在看戴銘老師的技術(shù)分享搅方,感覺收獲很多≌雷澹基于最近的學(xué)習(xí)姨涡,小編總結(jié)了一些App啟動優(yōu)化上的知識點(diǎn),并計(jì)劃落地一系列App啟動優(yōu)化的文章吧慢。

目錄如下:
iOS App啟動優(yōu)化(一)—— 了解App的啟動流程
iOS App啟動優(yōu)化(二)—— 使用“Time Profiler”工具監(jiān)控App的啟動耗時
iOS App啟動優(yōu)化(三)—— 自己做一個工具監(jiān)控App的啟動耗時


本篇將介紹App的兩種啟動方式:“冷/熱啟動”涛漂、App完整啟動流程以及“優(yōu)化思路”。

一、“冷啟動”與“熱啟動”

首先匈仗,我們先來區(qū)分兩個啟動的概念瓢剿。

  • 冷啟動:
    App點(diǎn)擊啟動前,此時App的進(jìn)程還不在系統(tǒng)里悠轩。
    需要系統(tǒng)新創(chuàng)建一個進(jìn)程分配給App间狂。(這是一次完整的App啟動過程)

  • 熱啟動:
    App在冷啟動后用戶將App退回后臺,此時App的進(jìn)程還在系統(tǒng)里火架。
    用戶重新返回App的過程鉴象。(熱啟動做的事較少)

主要區(qū)別:

名稱 區(qū)別
冷啟動 啟動時,App的進(jìn)程不在系統(tǒng)里何鸡,需要開啟新進(jìn)程纺弊。
熱啟動 啟動時,App的進(jìn)程還在系統(tǒng)里骡男,不需要開啟新進(jìn)程淆游。

二、App的完整啟動流程(冷啟動流程)

主要分為三個階段:

  1. main() 函數(shù)執(zhí)行前(pre-main階段)
  2. main() 函數(shù)執(zhí)行后(從main函數(shù)執(zhí)行隔盛,到設(shè)置self.window.rootViewController執(zhí)行完成)
  3. 首屏渲染完成后(從self.window.rootViewController執(zhí)行完成到didFinishLaunchWithOptions方法作用域結(jié)束)

(1)main函數(shù)執(zhí)行前稽犁,系統(tǒng)會做的事:
  • 加載可執(zhí)行文件。(App里的所有.o文件)

  • 加載動態(tài)鏈接庫骚亿,進(jìn)行rebase指針調(diào)整和bind符號綁定已亥。

  • ObjCruntime初始化。
    包括:ObjC相關(guān)Class的注冊来屠、category注冊虑椎、selector唯一性檢查等。

  • 初始化俱笛。
    包括:執(zhí)行+load()方法捆姜、用attribute((constructor))修飾的函數(shù)的調(diào)用、創(chuàng)建C++靜態(tài)全局變量等迎膜。

簡單來說泥技,
App啟動后,首先磕仅,系統(tǒng)內(nèi)核(Kernel)創(chuàng)建一個進(jìn)程珊豹。
其次,加載可執(zhí)行文件榕订。(可執(zhí)行文件是指Mach-O格式的文件店茶,也就是App中所有.o文件的集合體)這時,能獲取到dyld(dyld是蘋果的動態(tài)鏈接器)的路徑劫恒。
然后贩幻,加載dyld轿腺,主要分為4步:
1 . load dylibs:這一階段dyld會分析應(yīng)用依賴的dylib,找到其mach-o文件丛楚,打開和讀取這些文件并驗(yàn)證其有效性族壳,接著會找到代碼簽名注冊到內(nèi)核,最后對dylib的每一個segment調(diào)用mmap()趣些。
2 . rebase/bind:進(jìn)行rebase指針調(diào)整和bind符號綁定决侈。
3 . ObjC setup:runtime運(yùn)行時初始化。包括ObjC相關(guān)Class的注冊喧务、category注冊、selector唯一性檢查等枉圃。
4 . Initializers:調(diào)用每個ObjC類與分類的+load方法功茴,調(diào)用attribute((constructor))修飾的函數(shù)、創(chuàng)建C++靜態(tài)全局變量孽亲。


(2)main函數(shù)執(zhí)行后:

main函數(shù)執(zhí)行后的階段坎穿,指的是:從 main 函數(shù)執(zhí)行開始,到 appDelegatedidFinishLaunchingWithOptions方法里首屏渲染相關(guān)方法執(zhí)行完成返劲。
即玲昧,從main函數(shù)執(zhí)行到設(shè)置self.window.rootViewController執(zhí)行完成的階段。

  • 首屏初始化所需配置文件的讀寫操作篮绿;

  • 首屏列表大數(shù)據(jù)的讀确跹印;

  • 首屏渲染的大量計(jì)算亲配;

main函數(shù)執(zhí)行后

(3)首屏渲染完成后:

首屏渲染完成后的階段尘应,指的是:didFinishLaunchingWithOptions方法作用域
內(nèi)執(zhí)行首屏渲染后的所有方法執(zhí)行。
即從設(shè)置self.window.rootViewControllerdidFinishLaunchWithOptions方法作用域結(jié)束吼虎。

這個階段犬钢,首屏已經(jīng)渲染完成。

需要做的事:

  • 初始化一些首屏展示不需要的功能思灰。

  • 優(yōu)化主線程玷犹,先處理會卡住主線程的方法,不能影響到用戶的后續(xù)操作洒疚。


三歹颓、具體優(yōu)化思路

用戶能感知到的啟動時長主要是在 “main函數(shù)執(zhí)行前”“main函數(shù)執(zhí)行后到首屏渲染完成”的階段油湖。

main函數(shù)執(zhí)行前晴股,優(yōu)化思路如下:

(1)減少使用 +load() 方法
  • 方案一:如果可能的話,將+load中的內(nèi)容肺魁,放到渲染完成后做电湘。

  • 方案二:使用+initialize()的方法代替+load(),注意把邏輯移動到+initialize()時,要注意避免+initialize()的重復(fù)調(diào)用問題寂呛,可以使用dispatch_once()讓邏輯只執(zhí)行一次怎诫。

小知識點(diǎn):+load()+initialize()兩者的區(qū)別?
+load()方法會在main()函數(shù)調(diào)用前就調(diào)用,而+initialize()是在類第一次使用時才會調(diào)用贷痪。
+load方法的調(diào)用優(yōu)先級: 父類 > 子類 > 分類幻妓,并且不會被覆蓋,均會調(diào)用劫拢。
+load方法是在main() 函數(shù)之前調(diào)用肉津,所有的類文件都會加載,包括分類也會加載舱沧。
+initialize方法的調(diào)用優(yōu)先級:分類 > 子類妹沙,父類 > 子類。(父類的分類重寫了+initialize方法會覆蓋父類的+initialize方法)

(2)合并多個動態(tài)庫

蘋果公司建議使用更少的動態(tài)庫熟吏,并且建議在使用動態(tài)庫的數(shù)量較多時距糖,盡量將多個動態(tài)庫進(jìn)行合并。數(shù)量上牵寺,蘋果公司最多可以支持6個非系統(tǒng)動態(tài)庫合并為一個悍引。

(3)優(yōu)化類、方法帽氓、全局變量

減少加載啟動后不會去使用的類或方法趣斤;少用C++全局變量;

main函數(shù)執(zhí)行后黎休,優(yōu)化方案如下:

(4)優(yōu)化首屏渲染前的功能初始化

main函數(shù)執(zhí)行后到首屏渲染完成前唬渗,只處理首屏渲染相關(guān)業(yè)務(wù)。
首屏渲染外的其他功能放到首屏渲染完成后去初始化奋渔。

(5)優(yōu)化主線程耗時操作镊逝,防止屏幕卡頓。

首先檢查首屏渲染前嫉鲸,主線程上的耗時操作撑蒜。將耗時操作滯后或異步處理。
通常的耗時操作有:網(wǎng)絡(luò)加載玄渗、編輯座菠、存儲圖片和文件等資源。
針對耗時操作做相對應(yīng)的優(yōu)化即可藤树。

最后浴滴,我是站在iOS業(yè)界巨人的肩膀上完成了App啟動優(yōu)化(一)、(二)岁钓、(三)升略,感謝戴銘老師精彩的技術(shù)分享微王。
另附上,戴銘老師課程鏈接:《iOS開發(fā)高手課》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末品嚣,一起剝皮案震驚了整個濱河市炕倘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翰撑,老刑警劉巖罩旋,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異眶诈,居然都是意外死亡涨醋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門逝撬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浴骂,“玉大人,你說我怎么就攤上這事球拦。” “怎么了帐我?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵坎炼,是天一觀的道長。 經(jīng)常有香客問我拦键,道長谣光,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任芬为,我火速辦了婚禮萄金,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘媚朦。我一直安慰自己氧敢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布询张。 她就那樣靜靜地躺著孙乖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪份氧。 梳的紋絲不亂的頭發(fā)上唯袄,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音蜗帜,去河邊找鬼恋拷。 笑死,一個胖子當(dāng)著我的面吹牛厅缺,可吹牛的內(nèi)容都是我干的蔬顾。 我是一名探鬼主播宴偿,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼阎抒!你這毒婦竟也來了酪我?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤且叁,失蹤者是張志新(化名)和其女友劉穎都哭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逞带,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡欺矫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了展氓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穆趴。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖遇汞,靈堂內(nèi)的尸體忽然破棺而出未妹,到底是詐尸還是另有隱情,我是刑警寧澤空入,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布络它,位于F島的核電站,受9級特大地震影響歪赢,放射性物質(zhì)發(fā)生泄漏化戳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一埋凯、第九天 我趴在偏房一處隱蔽的房頂上張望点楼。 院中可真熱鬧,春花似錦白对、人聲如沸掠廓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽却盘。三九已至,卻和暖如春媳拴,著一層夾襖步出監(jiān)牢的瞬間黄橘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工屈溉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留塞关,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓子巾,卻偏偏與公主長得像帆赢,于是被迫代替她去往敵國和親小压。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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