iOS性能優(yōu)化之啟動(dòng)優(yōu)化

應(yīng)用啟動(dòng)時(shí)間,直接影響用戶(hù)對(duì)一款應(yīng)用的判斷和使用體驗(yàn)。所以App的啟動(dòng)優(yōu)化相對(duì)來(lái)說(shuō)在整個(gè)App的性能優(yōu)化中占有一定位置。

App啟動(dòng)概念

通常分為冷啟動(dòng)和熱啟動(dòng)

如果程序剛被運(yùn)行過(guò)一次,那么程序的代碼會(huì)被dyld緩存起來(lái),因此即使殺掉進(jìn)程再次重啟加載時(shí)間也會(huì)相對(duì)快一點(diǎn),如果長(zhǎng)時(shí)間沒(méi)有啟動(dòng)或者當(dāng)前dyld的緩存已經(jīng)被其他應(yīng)用占據(jù),那么這次啟動(dòng)所花費(fèi)的時(shí)間就要長(zhǎng)一點(diǎn),這就分別是熱啟動(dòng)和冷啟動(dòng)的概念。

App的完整啟動(dòng)流程(冷啟動(dòng))

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é)束)

【通常又把2跟3當(dāng)做一塊】

pre-main階段做了什么

加載解析該APP的Info.plist文件,創(chuàng)建沙盒,根據(jù)Info.plist的配置檢查相應(yīng)權(quán)限狀態(tài)。

1、系統(tǒng)內(nèi)核創(chuàng)建一個(gè)進(jìn)程,然后加載可執(zhí)行文件(.o文件),讀取dyld路徑并運(yùn)行dyld動(dòng)態(tài)連接器、dyld是一個(gè)專(zhuān)門(mén)用來(lái)加載動(dòng)態(tài)鏈接庫(kù)的庫(kù),dyld從可執(zhí)行文件的依賴(lài)開(kāi)始, 遞歸加載所有的依賴(lài)動(dòng)態(tài)鏈接庫(kù)。

動(dòng)態(tài)鏈接庫(kù)包括:iOS 中用到的所有系統(tǒng) framework,加載OC runtime方法的libobjc,系統(tǒng)級(jí)別的libSystem,例如libdispatch(GCD)和libsystem_blocks (Block)。

以下是動(dòng)態(tài)鏈接庫(kù)加載的具體流程

2、讀取庫(kù)鏡像文件(load dylibs image)

3、進(jìn)行rebase指針調(diào)整(Rebase image)和bind符號(hào)綁定(Bind image)。

4、(Objc setup)ObjC的runtime初始化。 包括:ObjC相關(guān)Class的注冊(cè)、category注冊(cè)、selector唯一性檢查等。

5、(initializers)初始化。 包括:執(zhí)行Objc的+load()函數(shù),C++的構(gòu)造函數(shù)屬性函數(shù) 形如attribute((constructor)) ,非基本類(lèi)型的C++靜態(tài)全局變量的創(chuàng)建。

其中2、3、4屬于靜態(tài)調(diào)整(fix-up),到第5步開(kāi)始動(dòng)態(tài)調(diào)整,開(kāi)始在堆和堆棧中寫(xiě)入內(nèi)容。

上面整個(gè)事件由 dyld 主導(dǎo),完成運(yùn)行環(huán)境的初始化后,配合 ImageLoader 將二進(jìn)制文件按格式加載到內(nèi)存,動(dòng)態(tài)鏈接依賴(lài)庫(kù),并由 runtime 負(fù)責(zé)加載成 objc 定義的結(jié)構(gòu),所有初始化工作結(jié)束后,dyld 調(diào)用真正的 main 函數(shù)。

pre-main階段可做的優(yōu)化

減少不必要的framework,因?yàn)閯?dòng)態(tài)鏈接比較耗時(shí)

能選擇靜態(tài)庫(kù)就選擇靜態(tài)庫(kù),少用動(dòng)態(tài)庫(kù),必須依賴(lài)動(dòng)態(tài)庫(kù),則把多個(gè)非系統(tǒng)的動(dòng)態(tài)庫(kù)合并成一個(gè)動(dòng)態(tài)庫(kù)

check framework應(yīng)當(dāng)設(shè)為optional和required,optional會(huì)有些額外的檢查會(huì)導(dǎo)致加載變慢

合并或者刪減一些OC類(lèi),使用工具AppCode代碼檢查功能清理項(xiàng)目中沒(méi)用到的類(lèi)

減少項(xiàng)目文件中Category,刪減一些無(wú)用的靜態(tài)變量、刪減沒(méi)有被調(diào)用到或者已經(jīng)廢棄的方法

將不必須在+load方法中做的事情延遲到+initialize(一般用于初始化全局變量或靜態(tài)變量)?類(lèi)第一次被加載時(shí)調(diào)用+initialize

盡量不要用C++虛函數(shù)

main()調(diào)用之后的加載(APP初始化流程)

在main()被調(diào)用之后,App的主要工作就是初始化必要的服務(wù),顯示首頁(yè)內(nèi)容等。

App通常在AppDelegate類(lèi)中的didFinishLaunchingWithOptions方法中創(chuàng)建首頁(yè)需要展示的view,然后在當(dāng)前runloop的末尾,主動(dòng)調(diào)用CA::Transaction::commit完成視圖的渲染

APP初始化流程的優(yōu)化點(diǎn)

1.盡量使用純代碼而不是xib或者storyboard來(lái)進(jìn)行UI框架的搭建,尤其是使用的TabBarController這種,盡量避免使用xib和storyboard,因?yàn)閤ib和storyboard也還是要解析成代碼來(lái)渲染頁(yè)面,并且官網(wǎng)為了滿足更多的需求,必定做了更多的適配判斷處理,會(huì)多很多步驟。會(huì)增加代碼的執(zhí)行效率從而增加啟動(dòng)時(shí)長(zhǎng)。

2.盡量在application:didFinishLaunchingWithOptions:中代碼的執(zhí)行時(shí)間。能多線程就多線程,能后臺(tái)執(zhí)行就后臺(tái)執(zhí)行。部分加載可以選擇懶加載或者后臺(tái)加載。不要阻塞主線程從而造成啟動(dòng)時(shí)間加長(zhǎng)。

別的相關(guān)

ViewController的生命周期方法

1、initWithCoder(用sb)或initWithNibName(用xib或純代碼)

2、awakeFromNib ( xib加載完成時(shí)調(diào)用,純代碼不會(huì)調(diào)用)

3、loadView(重寫(xiě)可以不調(diào)用父類(lèi)的方法[super loadView])

[super loadView]會(huì)創(chuàng)建一個(gè)空白視圖(純代碼下,如果自己本身就需要?jiǎng)?chuàng)建視圖,那么無(wú)需調(diào)用[super loadView],造成了一些不必要的開(kāi)銷(xiāo))

4、viewDidLoad(各種初始化操作)

5、viewWillAppear(視圖將要出現(xiàn))

6、viewWillLayoutSubviews (需要調(diào)整view的Subviews子視圖的位置)

觸發(fā)viewWillLayoutSubviews的幾種情形

1、addSubview會(huì)觸發(fā)viewWillLayoutSubviews

2、設(shè)置self.view及子視圖的frame.size會(huì)觸發(fā)layoutSubviews,當(dāng)然前提是frame.size的值設(shè)置前后發(fā)生了變化,注意,此處不是origin,呼應(yīng)官方文檔上的邊界發(fā)生變化

3、滾動(dòng)一個(gè)UIScrollView(該scrollview有子視圖的時(shí)候)會(huì)觸發(fā)layoutSubviews

4、橫豎屏幕切換會(huì)觸發(fā)

7、viewDidLayoutSubviews(調(diào)整完成之后需要做的工作)

8、viewDidAppear(視圖已經(jīng)出現(xiàn))

9、viewWillDisappear(視圖即將消失)

10、viewDidDisappear(視圖消失)

11、dealloc (釋放掉init與viewDidLoad中創(chuàng)建的對(duì)象)

12、didReceiveMemoryWarning (內(nèi)存警告)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 冷啟動(dòng) 定義 從用戶(hù)點(diǎn)擊App圖標(biāo)開(kāi)始到appDelegate didFinishLaunching方法執(zhí)行完成為...
    佐_籩閱讀 1,376評(píng)論 0 7
  • 最近讀了幾篇文章,關(guān)于iOS啟動(dòng)優(yōu)化,目前看,只有這一篇全面透徹一點(diǎn)。 今日頭條iOS客戶(hù)端啟動(dòng)速度優(yōu)化 應(yīng)用啟動(dòng)...
    素還真人閱讀 621評(píng)論 0 3
  • 應(yīng)用啟動(dòng)時(shí)間,直接影響用戶(hù)對(duì)一款應(yīng)用的判斷和使用體驗(yàn)。頭條主app本身就包含非常多并且復(fù)雜度高的業(yè)務(wù)模塊(如新聞、...
    新_1740閱讀 478評(píng)論 0 2
  • 歡迎訪問(wèn)我的博客原文 當(dāng) App 中的業(yè)務(wù)模塊越來(lái)越多、越來(lái)越復(fù)雜,集成了更多的三方庫(kù),App 啟動(dòng)也會(huì)越來(lái)越慢,...
    FiTeen閱讀 5,458評(píng)論 0 12
  • 昨天約了同事逛街,我和她年齡相仿,我感覺(jué)我們倆不是同事,像是好朋友,就是很相投的那種。她比我小一歲,可是人...
    虛實(shí)人生閱讀 177評(píng)論 0 3

友情鏈接更多精彩內(nèi)容