iOS- 性能優(yōu)化(啟動患亿、電量传蹈、包體等)

隨著我們移動互聯(lián)網(wǎng)的興起到火爆,成千上萬款app營運而生,電商概荷、出行谭贪、音視頻专控、教育等等,五花八門漂彤,那么每一款A(yù)PP都會有對應(yīng)的人群去下載使用,那么用戶對一款app的鐘愛程度除了這款app很受喜愛和直接用途之外瞬逊,受大家喜愛并且留存在手機上長久不卸載的一個重要原因显歧,便是我們的app的性能,包括:啟動速度确镊、啟動后的流暢度士骤、app的安裝包體積、app運行對手機的電量消耗蕾域、app是否有閃退等拷肌,這幾個條件,決定了一款app是否優(yōu)秀旨巷。
下面我針對這幾個方面做下項目性能優(yōu)化的經(jīng)驗和知識點分享

目錄

  • 項目啟動
  • 項目運行
  • 安裝包體積
  • app的電量消耗

1.項目啟動

項目啟動環(huán)節(jié)巨缘,我們大致分為2種啟動:即冷啟動(Cold Launch
熱啟動(Warm Launch),針對優(yōu)化采呐,我們主要針對冷啟動

知識點:打印啟動時間

通過添加環(huán)境變量可以打印出APP的啟動時間分析(Edit scheme -> Run -> Arguments)
DYLD_PRINT_STATISTICS設(shè)置為1
如果需要更詳細的信息若锁,那就將DYLD_PRINT_STATISTICS_DETAILS設(shè)置為1

冷啟動大概又分為三個階段

1.dyld
2.Runtime
3.main函數(shù)

launch.png

dyld

dyld(dynamic link editor),Apple的動態(tài)鏈接器斧吐,可以用來裝載Mach-O文件(可執(zhí)行文件又固、動態(tài)庫等)
啟動APP時,dyld所做的事情有:

裝載APP的可執(zhí)行文件煤率,同時會遞歸加載所有依賴的動態(tài)庫
當dyld把可執(zhí)行文件仰冠、動態(tài)庫都裝載完畢后,會通知Runtime進行下一步的處理

具體關(guān)于dyld的講解蝶糯,我推薦一篇文章dyld專題講解洋只,寫的不錯,后續(xù)我也會對dyld寫篇自己的理解的博客

Runtime

這里說的Runtime并不是要對Runtime進行底層講解昼捍,是針對程序的啟動流程的Runtime階段進行分析识虚,推薦一篇關(guān)于Runtime的底層講解iOS底層原理總結(jié) - 探尋Runtime本質(zhì)(一)
啟動APP時,runtime所做的事情有

  • 調(diào)用map_images進行可執(zhí)行文件內(nèi)容的解析和處理
  • 在load_images中調(diào)用call_load_methods端三,調(diào)用所有Class和Category的+load方法
  • 進行各種objc結(jié)構(gòu)的初始化(注冊O(shè)bjc類 舷礼、初始化類對象等等)
  • 調(diào)用C++靜態(tài)初始化器和attribute((constructor))修飾的函數(shù)

到此為止,可執(zhí)行文件和動態(tài)庫中所有的符號(Class郊闯,Protocol妻献,Selector蛛株,IMP,…)都已經(jīng)按格式成功加載到內(nèi)存中育拨,被runtime 所管理

Main函數(shù)

main函數(shù)的調(diào)用谨履,便是我們熟知的項目中Main入口和AppDelegate類里面的那一系列的調(diào)用了

總結(jié)一下優(yōu)化方案,按照階段:

dyld

減少動態(tài)庫熬丧、合并一些動態(tài)庫(定期清理不必要的動態(tài)庫)
減少Objc類笋粟、分類的數(shù)量、減少Selector數(shù)量(定期清理不必要的類析蝴、分類)
減少C++虛函數(shù)數(shù)量
Swift盡量使用struct

Runtime

用+initialize方法和dispatch_once取代所有的attribute((constructor))害捕、C++靜態(tài)構(gòu)造器、ObjC的+load

Main函數(shù)

  • 在不影響用戶體驗的前提下闷畸,盡可能將一些操作延遲尝盼,不要全部都放在 finishLaunching方法中,例如三方注冊、啟動圖等
  • 按需加載

2.項目運行

其實項目運行優(yōu)化佑菩,就涉及到我們的代碼優(yōu)化了盾沫,最常見也是影響最大的,就是

卡頓現(xiàn)象

針對卡頓現(xiàn)象的原因和優(yōu)化我在這里大概列舉一下殿漠,我會在另一篇關(guān)于CPU和GPU赴精,以及離屏渲染等方向進行講解

CPU優(yōu)化策略:

1.盡量用輕量級的對象,比如用不到事件處理的地方绞幌,可以考慮使用CALayer取代UIView
2.不要頻繁地調(diào)用UIView的相關(guān)屬性蕾哟,比如frame、bounds莲蜘、transform等屬性渐苏,盡量減少不必要的修改
3.盡量提前計算好布局,在有需要時一次性調(diào)整對應(yīng)的屬性菇夸,不要多次修改屬性
4.Autolayout會比直接設(shè)置frame消耗更多的CPU資源
5.圖片的size最好剛好跟UIImageView的size保持一致
6.控制一下線程的最大并發(fā)數(shù)量
7.盡量把耗時的操作放到子線程
8.文本處理(尺寸計算、繪制)
9.圖片處理(解碼仪吧、繪制)

GPU優(yōu)化策略:

1.盡量避免短時間內(nèi)大量圖片的顯示庄新,盡可能將多張圖片合成一張進行顯示
2.GPU能處理的最大紋理尺寸是4096x4096,一旦超過這個尺寸薯鼠,就會占用3.CPU資源進行處理择诈,所以紋理盡量不要超過這個尺寸
4.盡量減少視圖數(shù)量和層次
5.減少透明的視圖(alpha<1),不透明的就設(shè)置opaque為YES
6.盡量避免出現(xiàn)離屏渲染

離屏渲染

在OpenGL中出皇,GPU有2種渲染方式
On-Screen Rendering:當前屏幕渲染羞芍,在當前用于顯示的屏幕緩沖區(qū)進行渲染操作
Off-Screen Rendering:離屏渲染,在當前屏幕緩沖區(qū)以外新開辟一個緩沖區(qū)進行渲染操作

離屏渲染消耗性能的原因:
1.需要創(chuàng)建新的緩沖區(qū)
2.離屏渲染的整個過程郊艘,需要多次切換上下文環(huán)境荷科,先是從當前屏幕(On-Screen)切換到離屏(Off-Screen)唯咬;等到離屏渲染結(jié)束以后,將離屏緩沖區(qū)的渲染結(jié)果顯示到屏幕上畏浆,又需要將上下文環(huán)境從離屏切換到當前屏幕

哪些操作會觸發(fā)離屏渲染胆胰?

  • 光柵化,layer.shouldRasterize = YES
  • 遮罩刻获,layer.mask
  • 圓角蜀涨,同時設(shè)置layer.masksToBounds = YES、layer.cornerRadius大于0
    考慮通過CoreGraphics繪制裁剪圓角蝎毡,或者叫美工提供圓角圖片
  • 陰影厚柳,layer.shadowXXX
    如果設(shè)置了layer.shadowPath就不會產(chǎn)生離屏渲染

卡頓檢測

我們平時所說的“卡頓”主要是因為在主線程執(zhí)行了比較耗時的操作

如何檢測?

可以添加Observer到主線程RunLoop中沐兵,通過監(jiān)聽RunLoop狀態(tài)切換的耗時别垮,以達到監(jiān)控卡頓的目的
當然網(wǎng)上還有更多的別的方案,后續(xù)我會針對這一塊進行講解痒筒,讀者可以留言別的方式交流

3.安裝包體積瘦身

首先我們要知道安裝包的組成成分

  • 可執(zhí)行文件
  • 資源(圖片宰闰、音頻、視頻等)
資源瘦身方案:
可執(zhí)行文件瘦身方案:
  • 編譯器優(yōu)化
    Strip Linked Product、Make Strings Read-Only老充、Symbols Hidden by Default設(shè)置為YES
    去掉異常支持葡盗,Enable C++ Exceptions、Enable Objective-C Exceptions設(shè)置為NO啡浊, Other C Flags添加-fno-exceptions
  • 利用AppCode(https://www.jetbrains.com/objc/)檢測未使用的代碼:菜單欄 -> Code -> Inspect Code
  • 編寫LLVM插件檢測出重復(fù)代碼觅够、未被調(diào)用的代碼

4.App的電量消耗優(yōu)化

首先我們要知道App好點的幾個主要來源


energy.png
  • CPU
  • 網(wǎng)絡(luò)請求任務(wù)
  • 定位
  • 圖片處理

我們大概從以下入手進行優(yōu)化,(視自己項目情況而定):

1.盡可能降低CPU巷嚣、GPU功耗
2.盡可能少用定時器
3.優(yōu)化I/O操作

1.盡量不要頻繁寫入小數(shù)據(jù)喘先,最好批量一次性寫入
2.讀寫大量重要數(shù)據(jù)時,考慮用dispatch_io廷粒,其提供了基于GCD的異步操作文件I/O的API窘拯。用dispatch_io系統(tǒng)會優(yōu)化磁盤訪問
3.數(shù)據(jù)量比較大的,建議使用數(shù)據(jù)庫(比如SQLite坝茎、CoreData)

4.網(wǎng)絡(luò)優(yōu)化

1.減少涤姊、壓縮網(wǎng)絡(luò)數(shù)據(jù)
2.如果多次請求的結(jié)果是相同的,盡量使用緩存
3.使用斷點續(xù)傳嗤放,否則網(wǎng)絡(luò)不穩(wěn)定時可能多次傳輸相同的內(nèi)容
4.網(wǎng)絡(luò)不可用時思喊,不要嘗試執(zhí)行網(wǎng)絡(luò)請求
5.讓用戶可以取消長時間運行或者速度很慢的網(wǎng)絡(luò)操作,設(shè)置合適的超時時間
批量傳輸次酌,比如恨课,下載視頻流時舆乔,不要傳輸很小的數(shù)據(jù)包,直接下載整個文件或者一大塊一大塊地下載庄呈。如果下載廣告蜕煌,一次性多下載一些,然后再慢慢展示诬留。如果下載電子郵件斜纪,一次下載多封,不要一封一封地下載

5.定位優(yōu)化

1.如果只是需要快速確定用戶位置文兑,最好用CLLocationManagerrequestLocation方法盒刚。定位完成后,會自動讓定位硬件斷電
2.如果不是導(dǎo)航應(yīng)用绿贞,盡量不要實時更新位置因块,定位完畢就關(guān)掉定位服務(wù)
3.盡量降低定位精度,比如盡量不要使用精度最高的kCLLocationAccuracyBest
需要后臺定位時籍铁,盡量設(shè)置pausesLocationUpdatesAutomatically為YES涡上,如果用戶不太可能移動的時候系統(tǒng)會自動暫停位置更新
4.盡量不要使用startMonitoringSignificantLocationChanges,優(yōu)先考慮startMonitoringForRegion:

6.硬件檢測優(yōu)化

用戶移動拒名、搖晃吩愧、傾斜設(shè)備時,會產(chǎn)生動作(motion)事件增显,這些事件由加速度計雁佳、陀螺儀、磁力計等硬件檢測同云。在不需要檢測的場合糖权,應(yīng)該及時關(guān)閉這些硬件

結(jié)尾

到這里,對app的優(yōu)化就基本說完了炸站,大家可以留言交流更好的優(yōu)化方案星澳,文章如有錯誤或者理解不到位之處,希望大家指點旱易,有幫助的老鐵們募判,點個喜歡,謝謝
Github: https://github.com/shLuckySeven

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咒唆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子释液,更是在濱河造成了極大的恐慌全释,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件误债,死亡現(xiàn)場離奇詭異浸船,居然都是意外死亡妄迁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門李命,熙熙樓的掌柜王于貴愁眉苦臉地迎上來登淘,“玉大人,你說我怎么就攤上這事封字∏荩” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵阔籽,是天一觀的道長流妻。 經(jīng)常有香客問我,道長笆制,這世上最難降的妖魔是什么绅这? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮在辆,結(jié)果婚禮上证薇,老公的妹妹穿的比我還像新娘。我一直安慰自己匆篓,他們只是感情好浑度,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奕删,像睡著了一般俺泣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上完残,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天伏钠,我揣著相機與錄音,去河邊找鬼谨设。 笑死熟掂,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的扎拣。 我是一名探鬼主播赴肚,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼二蓝!你這毒婦竟也來了誉券?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤刊愚,失蹤者是張志新(化名)和其女友劉穎踊跟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸥诽,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡商玫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年箕憾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拳昌。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡袭异,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出炬藤,到底是詐尸還是另有隱情御铃,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布刻像,位于F島的核電站畅买,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏细睡。R本人自食惡果不足惜谷羞,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望溜徙。 院中可真熱鬧湃缎,春花似錦、人聲如沸蠢壹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽图贸。三九已至蹂季,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疏日,已是汗流浹背偿洁。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留沟优,地道東北人涕滋。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像挠阁,于是被迫代替她去往敵國和親宾肺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

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