iOS App 整體性能優化

性能優化是一個大的問題,所以首先是需要把這個問題分而化之,把它分解成一個個影響app性能的小問題才能進行回答,所以在這里做出一些整理來回答這個問題,同時也提醒自己再次遇到如此大的問題時學會分析問題的本身以及從哪些方面去回答這些問題。
影響app性能的幾個問題有:

1. 網絡性能

網絡性能優化涉及到DNS解析,路由算法,以及服務器端性能,不是很了解,可參看一下文章:
攜程App的網絡性能優化實踐
影響移動應用網絡性能的三大因素

2. 內存問題

在MRC時代,手動釋放內存會導致大量內存的泄露。但是在ARC時代解決了大部分的內存泄露,但是仍然會出現內存泄露的問題:

1. 循環引用
2. Core Animation對象手動釋放
3. UIWebView內存泄露

一些詳細介紹如下:
ARC下的內存泄漏
ARC 下內存泄露的那些點

3. 主線程阻塞

所有的用戶輸入和UIKit的渲染是在主線程執行。所以要保證app的流暢度就一定不能阻塞主線程,把可以在子線程中做的事放到子線程中來減少主線程的計算與處理。
假如在主線程中執行如下操作:

1. 網絡同步請求
2. I/O操作
3. 大量運算
4. 解壓縮
...

因為需要處理的多所以會阻塞主線程,導致卡頓,因此要減少主線程中耗時的操作,使用多線程(NSThread、NSOperationQueue, GCD)來處理這些。可以查看OS X 和 iOS 中的多線程技術關于多線程的介紹。還有主線程關于渲染的處理會影響效率,所以這一塊也是需要處理的。

4. Offscreen rendering(離屏渲染)

離屏渲染,指的是GPU在當前屏幕緩沖區以外新開辟一個緩沖區進行渲染操作。離屏渲染意味著你App的部分區域每一幀渲染了兩次。所以會造成一定的性能損失。
對于UIView或者CALayer的frame,bounds,transform等屬性的改變,消耗的資源遠大于他們其他的屬性改變。
可以參考以下文章:
繪制像素到屏幕上
繪制陰影引發的 iOS 繪圖性能問題總結
iOS 離屏渲染的研究

5. 圖片的處理

通常會用imageNamed:來加載mainbundle中的圖片,此函數會緩存加載的image。因此,對于那些被重用的圖片,這個API很高效。但是對于那些使用很少的圖片,用這個就很耗內存。
所以在加載使用一次的應用圖片時使用initWithContentsOfFile:函數,而在加載多次使用的圖片時就使用imageNamed:函數。例如加載引導頁的圖片時使用載入路徑的方式,而使用通用的背景圖的就使用imageNamed:的方式。

//使用路徑方式載入圖片
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:fileType]; 
UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];  

//使用圖片名的方式載入圖片
UIImage *image = [UIImage imageNamed:fileName];  

//讀取本地圖片的 和imageNamed一樣,但是性能比后者要強很多,兩個參數,前面一個是 文件名,后面一個是類型
#define LoadImage(_pointer) [UIImage imageNamed:[UIUtil imageName:_pointer]] //可以用來直接傳圖片名字
#define LoadImageWithType(file,ext) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:file ofType:ext]]

一般的優化技術就是在減少內存使用,減少主線程業務處理,用空間來換時間等等,基于這些策略及技術考慮來選擇優化方向。
以下是iOS的一些細節優化策略

  • 避免對UIView使用透明。(UIView默認是非透明)。原因是透明對性能要求較高,如果在滾動時頁面比較復雜,體驗上的差異會相對明顯。
  • 避免過于龐大的xib。(如果不得不使用一個ViewController作為xib,也應該將其其中的子視圖拆成小的xib)。
    需要注意的是,當你加載一個XIB的時候所有內容都被放在了內存里,包括任何圖片。如果有一個不會即刻用到的view,你這就是在浪費寶貴的內存資源了。Storyboards就是另一碼事兒了,storyboard僅在需要時實例化一個view controller.
    不要阻塞主線程。
  • 使圖片符合UIImageView的尺寸。不要在運行的時候再讓UIImageView自行壓縮,因為這樣會降低運行時的性能。(注:手動壓縮圖片的方法,在context中使用drawInRect)
  • 選擇合適的collection,數據結構決定了算法的效率。 如:Array使用下標查找較快,但插入和刪除較慢。set進行插入和刪除很快。
  • 使用緩存,因為數據具有時效的,所以對于時效性要求不高的數據完全可以使用緩存來保證快速顯示。例如URL對應的圖片緩存(SDWebImage),通過數據庫活core Data來保存不需要變動的數據,UIWeb的緩存等都屬于這種。
  • 處理低內存警告。在收到內存警告時,清除對cache的強引用,沒有當前顯示需要的image,以及一些其他可以再創建的對象。
  • 重用一些高消耗的對象,如NSDateFormatter、NSCalender等。解決方法:可以將其作為property、甚至是靜態變量作為單例在APP中使用。并且,NSDateFormatter的 setDateFormate也是非常消耗資源的一個操作。
  • 網絡傳輸過來的數據,往往是json或xml字符串。直接將這些字符串轉換成我們需要的數據結構(自定義類或者NSDictionary),避免后續使用的時候還要做數據結構轉換產生不必要的消耗。
  • 設置UIView的背景圖片時,如果是整幅圖,就采用addSubView一個UIImageView;如果是要重復平鋪一個小圖,就使用colorWithPatternImage,因為這個函數的設計上就是針對小圖的,如果用于整幅大圖來做背景,反而會消耗更多內存。
  • 在臨時創建大量對象時,使用NSAutoreleasepool,例如,一個循環用于創建包含多個對象的數組,在循環體內,即可使用@autoreleasepool包裹創建代碼。使用系統的@autoreleasepool會有延遲,內存不會馬上釋放。
  • 對于排版復雜的文字或者圖文混排,使用CoreText技術。(而不是一味地堆UILabel)
  • 在對渲染的效率要求較高的頁面中,避免使用UILabel、UITextView等在主線程中進行排版和繪制的控件。應自定義文本控件,用TextKit或者CoreText進行文本異步繪制。另外,還有facebook的AsyncDisplayKit框架可以采用。
    將繪制圖像放在次線程中執行,如在次線程中使用 CGContext進行畫圖,在主線程中 layer.contents = img。
    圖片和視圖的大小避免超過4096*4096,因為這是目前iphone5到iphone6p以及ipad僅僅通過GPU就直接處理的紋理尺寸上限,否則就GPU就會提交CPU先處理,這樣開銷很大。
  • 減少視圖或者layer的層級數量,在有多個層級時,可以將多圖合并成一張圖,再渲染顯示。
  • 電量消耗:減少耗電與流量的操作。GPS在獲取用戶位置之后,就進行關閉,因為它非常耗電。
  • 關于后臺運行。進入后臺后,即盡量減少內存占用、釋放所有的共享資源(如Calender或address book),因為iOS會kill后臺中內存消耗最多的或者進入后臺還占用共享資源的進程。

參考文章:
iOS App性能優化
讓App的運行速度與響應速度趨于一流
程序猿進化必讀:讓App的運行速度與響應速度趨于一流(iOS)
iOS應用性能調優的4個建議和技巧

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,705評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,162評論 4 61
  • 有的時候,選擇比努力重要!一個好的選擇可能比你努力一百天更有效!可是,有了好的選擇,不努力,卻又是萬萬行不通的,只...
    亨謙閱讀 184評論 0 2
  • 里面包含了證書創建、上線前的資料填寫等等一套完整的流程。 http://blog.csdn.net/zgxiaoj...
    湘郎閱讀 336評論 0 0
  • 題綱: db.collection.find()/findOne() 問與答 問: 有辦法查詢字段值為null的文...
    螞蟻閑游閱讀 356評論 0 0