本篇主要記錄一下我對界面優化上的一些探索。關於時間優化的探索將會在中篇裏進行介紹。下篇將主要介紹一些耗電優化、安裝包瘦身的探索。php
要了解卡頓原理,須要對幀緩衝區、垂直同步、CPU 和 GPU 幾個詞進行一下了解,而後綜合起來,就能夠獲得卡頓的答案。本篇我就按照本身的理解來進行描述,若有不當,歡迎指正。ios
聽起來很高大上,其實就是用來存放每一幀畫面數據的一個「倉庫」,一個倉庫只存放一幀畫面的數據,iOS 一直是雙緩存,就是有兩個倉庫,存當前幀數據的叫「正式倉庫」,存下一幀數據的叫「預備倉庫」。git
當正式倉庫的數據被取走後,二者身份交換,原來的預備倉庫轉正爲正式倉庫,原來的正式倉庫變成預備倉庫。github
就是一個「信號」,通知 app 該開始準備往預備倉庫裏存放數據了,系統過一會就要來取,這個時間大概是16毫秒。緩存
主要的工做有:正式對象的建立和銷燬、對象屬性的調整、佈局計算、文本的計算和排版、圖片的格式轉換和解碼、圖像的繪製。咱們能夠理解爲負責包裹內部的處理工做,簡稱「打包」。性能優化
主要的工做有:將 CPU 計算好的內容進行變換、合成、渲染等處理,而後將渲染結果提交到幀緩衝區。咱們能夠理解爲,對 CPU 給過來的包裹進行分類、排列等操做後,存放到倉庫裏去,簡稱「入庫」。app
當收到系統發過來的 VSync 「信號」後,CPU 就開始對這一幀畫面的數據進行「打包」,而後交給 GPU 進行「入庫」操做,存入到「預備倉庫」中。框架
16毫秒後,預備倉庫轉正,系統開始讀取倉庫裏的數據,若是這個時候,倉庫中的數據尚未準備好,那麼系統就會發脾氣,放棄讀取倉庫中的數據。異步
那麼這個時候,由於系統的寧缺毋濫,致使了顯示器上顯示的仍是上一幀畫面,就形成了卡頓的效果。佈局
做爲軟件開發工程師的咱們,既不能延長16毫秒的處理時間,也不能改變系統的脾氣,那咱們能作的就是儘可能在這個時間內完成數據的準備。要麼「打包」快一點,要麼「入庫」快一點,也就是針對 CPU 和 GPU 的工做進行優化,這就是性能優化的工做了。
UITableViewCell 和 UICollectionViewCell 的複用,能夠減小 cell 的建立操做;
儘可能使用輕量級的對象,能夠減小對象的建立時間,好比在不須要事件處理的場景裏,使用CALayer 比 UIView 會更加合適;
表情鍵盤使用 UICollectionViewCell 代替 UIButton,能夠減小對象的建立操做;
對象不涉及UI操做,放到後臺線程建立;
性能要求嚴格的界面,storyborad的資源消耗>代碼建立;
推遲對象建立的時間,對象放到多個任務中,好比懶加載;
UITableViewCell 高度提早計算並存儲,要用的時候直接讀取;
frame 計算好,較少沒必要要的修改;
Autolayout會比直接設置frame消耗更多的CPU資源;
普通文本能夠在子線程用 [NSAttributedString boundingRectWithSize:options:context:] 來計算文本寬高,用 -[NSAttributedString drawWithRect:options:context:] 來繪製文本;
CoreText 對象佔用內存較少,當顯示大量文本時,能夠用 CoreText 對文本異步繪製;
UITableViewCell 滑動減速的時候才加載圖片,能夠參考這個demo;
加載圖片時,imageNamed 方法默認加載圖片成功後會內存中緩存圖片,下次讀取會很快;imageWithContentsOfFile 方法不會緩存圖片,大圖片可使用該方法;
儘可能不要讓圖片和視圖的大小超過 GPU 紋理尺寸上限:4096×4096,否則圖片還須要通過 CPU 的處理;
儘可能減小視圖數量和層次,並設置視圖爲不透明,UIView 的不透明屬性 (opaque) 默認爲 YES,通常設置背景顏色便可;CALayer 的不透明屬性 (opaque) 默認爲 NO,須要設置爲 YES;
CALayer 的 border、圓角、陰影、遮罩,一般會觸發離屏渲染,儘可能少用,圓角屬性可使用 CoreGraphics 繪製或使用圓角圖片代替,關於離屏渲染的知識,具體能夠參考這篇文章:iOS 圖形性能優化;
圖片的 size 最好恰好跟 UIImageView 的 size 保持一致,這涉及到像素對齊的知識,也能夠在上面這篇文章中詳細瞭解;
最後鄭重聲明,本篇裏只是記錄一下個人我的理解和代碼實踐,資料大量參考了這篇文章:iOS 保持界面流暢的技巧,做者是寫出了 YYKit 框架的大牛,想要深刻學習的朋友請移步。
本篇的界面優化就記錄到這裏,後面會持續更新,歡迎指正。