自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

App啟動速度優(yōu)化看過來

移動開發(fā)
總結(jié)起來,好像APP啟動速度優(yōu)化就一句話:讓系統(tǒng)在啟動期間少做一些事。當(dāng)然我們得先清楚工程里做的哪些事是在啟動期間做的、對啟動速度的影響有多大,然后case by case地分析工程代碼,通過放到子線程、延遲加載、懶加載等方式讓系統(tǒng)在啟動期間更輕松些。

應(yīng)用啟動流程

iOS應(yīng)用的啟動可分為pre-main階段和main()階段,其中系統(tǒng)做的事情依次是:

pre-main階段

  • 1.1. 加載應(yīng)用的可執(zhí)行文件
  • 1.2. 加載動態(tài)鏈接庫加載器dyld(dynamic loader)
  • 1.3. dyld遞歸加載應(yīng)用所有依賴的dylib(dynamic library 動態(tài)鏈接庫)

main()階段

  • 2.1. dyld調(diào)用main()
  • 2.2. 調(diào)用UIApplicationMain()
  • 2.3. 調(diào)用applicationWillFinishLaunching
  • 2.4. 調(diào)用didFinishLaunchingWithOptions

啟動耗時(shí)的測量

在進(jìn)行優(yōu)化之前,我們首先應(yīng)該能測量各階段的耗時(shí)。

[[245149]]

1. pre-main階段

對于pre-main階段,Apple提供了一種測量方法,在 Xcode 中 Edit scheme -> Run -> Auguments 將環(huán)境變量DYLD_PRINT_STATISTICS 設(shè)為1 。之后控制臺會輸出類似內(nèi)容:

 

  1. Total pre-main time: 228.41 milliseconds (100.0%) 
  2.          dylib loading time:  82.35 milliseconds (36.0%) 
  3.         rebase/binding time:   6.12 milliseconds (2.6%) 
  4.             ObjC setup time:   7.82 milliseconds (3.4%) 
  5.            initializer time: 132.02 milliseconds (57.8%) 
  6.            slowest intializers : 
  7.              libSystem.B.dylib : 122.07 milliseconds (53.4%) 
  8.                 CoreFoundation :   5.59 milliseconds (2.4%) 

這樣我們可以清晰的看到每個(gè)耗時(shí)了。

2.main()階段

mian()階段主要是測量mian()函數(shù)開始執(zhí)行到didFinishLaunchingWithOptions執(zhí)行結(jié)束的時(shí)間,我們直接插入代碼就可以了。

 

  1. CFAbsoluteTime StartTime; 
  2. int main(int argc, char * argv[]) { 
  3. StartTime = CFAbsoluteTimeGetCurrent(); 

再在AppDelegate.m文件中用extern聲明全局變量StartTime

  1. extern CFAbsoluteTime StartTime; 

***在didFinishLaunchingWithOptions里,再獲取一下當(dāng)前時(shí)間,與StartTime的差值即是main()階段運(yùn)行耗時(shí)。

  1. double launchTime = (CFAbsoluteTimeGetCurrent() - StartTime); 

改善啟動時(shí)間

pre-main階段

在這一階段,我們能做的主要是優(yōu)化dylib

加載 Dylib

之前提到過加載系統(tǒng)的 dylib 很快,因?yàn)橛袃?yōu)化。但加載內(nèi)嵌(embedded)的 dylib 文件很占時(shí)間,所以盡可能把多個(gè)內(nèi)嵌 dylib 合并成一個(gè)來加載,或者使用 static archive。

使用 dlopen() 來在運(yùn)行時(shí)懶加載是不建議的,這么做可能會帶來一些問題,并且總的開銷更大。

Rebase/Binding

之前提過 Rebaing 消耗了大量時(shí)間在 I/O 上,而在之后的 Binding 就不怎么需要 I/O 了,而是將時(shí)間耗費(fèi)在計(jì)算上。所以這兩個(gè)步驟的耗時(shí)是混在一起的。

之前說過可以從查看 __DATA 段中需要修正(fix-up)的指針,所以減少指針數(shù)量才會減少這部分工作的耗時(shí)。對于 ObjC 來說就是減少 Class,selector 和 category 這些元數(shù)據(jù)的數(shù)量。從編碼原則和設(shè)計(jì)模式之類的理論都會鼓勵大家多寫精致短小的類和方法,并將每部分方法獨(dú)立出一個(gè)類別,其實(shí)這會增加啟動時(shí)間。對于 C++ 來說需要減少虛方法,因?yàn)樘摲椒〞?chuàng)建 vtable,這也會在 __DATA 段中創(chuàng)建結(jié)構(gòu)。雖然 C++ 虛方法對啟動耗時(shí)的增加要比 ObjC 元數(shù)據(jù)要少,但依然不可忽視。

Objc setup

大部分ObjC初始化工作已經(jīng)在Rebase/Bind階段做完了,這一步dyld會注冊所有聲明過的ObjC類,將分類插入到類的方法列表里,再檢查每個(gè)selector的唯一性。

在這一步倒沒什么優(yōu)化可做的,Rebase/Bind階段優(yōu)化好了,這一步的耗時(shí)也會減少。

Initializers

到了這一階段,dyld開始運(yùn)行程序的初始化函數(shù),調(diào)用每個(gè)Objc類和分類的+load方法,調(diào)用C/C++ 中的構(gòu)造器函數(shù)(用attribute((constructor))修飾的函數(shù)),和創(chuàng)建非基本類型的C++靜態(tài)全局變量。Initializers階段執(zhí)行完后,dyld開始調(diào)用main()函數(shù)。

在這一步,我們可以做的優(yōu)化有:

  1. 少在類的+load方法里做事情,盡量把這些事情推遲到+initiailize
  2. 減少構(gòu)造器函數(shù)個(gè)數(shù),在構(gòu)造器函數(shù)里少做些事情
  3. 減少C++靜態(tài)全局變量的個(gè)數(shù)

main()階段的優(yōu)化

這一階段的優(yōu)化主要是減少didFinishLaunchingWithOptions方法里的工作,在didFinishLaunchingWithOptions方法里,我們會創(chuàng)建應(yīng)用的window,指定其rootViewController,調(diào)用window的makeKeyAndVisible方法讓其可見。由于業(yè)務(wù)需要,我們會初始化各個(gè)二方/三方庫,設(shè)置系統(tǒng)UI風(fēng)格,檢查是否需要顯示引導(dǎo)頁、是否需要登錄、是否有新版本等,由于歷史原因,這里的代碼容易變得比較龐大,啟動耗時(shí)難以控制。

所以,滿足業(yè)務(wù)需要的前提下,didFinishLaunchingWithOptions在主線程里做的事情越少越好。在這一步,我們可以做的優(yōu)化有:

  1. 梳理各個(gè)二方/三方庫,找到可以延遲加載的庫,做延遲加載處理,比如放到首頁控制器的viewDidAppear方法里。
  2. 梳理業(yè)務(wù)邏輯,把可以延遲執(zhí)行的邏輯,做延遲執(zhí)行處理。比如檢查新版本、注冊推送通知等邏輯。
  3. 避免復(fù)雜/多余的計(jì)算。
  4. 避免在首頁控制器的viewDidLoad和viewWillAppear做太多事情,這2個(gè)方法執(zhí)行完,首頁控制器才能顯示,部分可以延遲創(chuàng)建的視圖應(yīng)做延遲創(chuàng)建/懶加載處理。
  5. 首頁控制器用純代碼方式來構(gòu)建。

總結(jié)

總結(jié)起來,好像啟動速度優(yōu)化就一句話:讓系統(tǒng)在啟動期間少做一些事。當(dāng)然我們得先清楚工程里做的哪些事是在啟動期間做的、對啟動速度的影響有多大,然后case by case地分析工程代碼,通過放到子線程、延遲加載、懶加載等方式讓系統(tǒng)在啟動期間更輕松些。

責(zé)任編輯:未麗燕 來源: 簡書
相關(guān)推薦

2013-10-14 14:15:21

程序員讀書

2009-08-05 09:37:11

云計(jì)算CIO

2020-11-05 10:57:47

云計(jì)算多云公有云

2015-11-30 14:10:49

大無線eLTE華為

2009-10-20 14:10:00

CCIE考試

2022-05-11 07:17:29

MySQLAnsible運(yùn)維

2013-11-08 17:33:52

2015-09-15 09:12:04

程序媛Google特殊獎勵

2011-05-27 11:21:58

打印機(jī)技巧

2015-02-09 13:48:12

2019-08-08 17:14:31

5G手機(jī)華為三星

2012-03-31 11:05:00

水冷服務(wù)器液體刀片服務(wù)器

2017-10-12 12:13:09

設(shè)計(jì)師搜索功能搜索框

2015-02-27 15:14:05

2019-01-24 10:18:25

機(jī)器學(xué)習(xí)深度學(xué)習(xí)圖像處理

2013-05-23 11:22:04

Android開發(fā)者UI設(shè)計(jì)Android設(shè)計(jì)

2020-05-26 15:16:44

5G兩會全息

2009-03-25 19:05:24

四核服務(wù)器AMD

2020-10-29 12:53:28

JavaScriptTypeScript開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號