手機性能優化的重點,就是界面渲染。通常,計算任務都交給服務端。html
界面渲染慢,就很差了。git
常見的離屏渲染代碼: 繪製陰影,github
var label = UILabel()
label.layer.shadowColor = UIColor.lightGray.cgColor
label.layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
label.layer.shadowOpacity = 1.0
label.layer.shadowRadius = 5.0
label.text = "離屏渲染"
複製代碼
寫完之後,CPU 和 GPU 都沒有充足的信息繪製陰影效果。api
過程是, CPU 會先把文本傳出去,請求 GPU (CPU 把文本傳給 GPU ),建立一個內存中的位圖上下文(GPU 把文本放進去 ),離屏渲染這就開始了。緩存
這個上下文缺信息,不在屏幕上, 不是幀緩衝。(渲染出來的圖形上下文,不屬於當前幀)。性能優化
而後,CPU 拿到渲染好的文字,基於渲染出來的每個像素的透明度,計算出陰影的形狀。bash
最後,CPU 把最新計算出來的文字陰影形狀的信息,傳給 GPU . GPU 有陰影信息,有以前圖形上下文的渲染文本,GPU 就渲染好了最終的文字及其陰影,交給幀緩衝 (Frame Buffer), 咱們就看到了。app
這段代碼要渲染兩次,出現了離屏渲染。對 GPU 的性能有影響。他須要等待 CPU 來算出陰影的形狀。框架
由於咱們要 60 的幀數 ( FPS ), GPU 準備幀緩衝,渲染出當前幀,只有 17 毫秒的時間。拖累了主線程,屏幕刷新不過來。ide
layer 的四個屬性 shadowColor , shadowOffset ,shadowOpacity ,shadowRadius ,通常性能很差。
對於一個視圖框, 經過 layer 在周邊加陰影。用 layer 的 shadowPath,建立一個 UIBezierPath,
UIBezierPath(rect: CGRect(x: 0, y: 0, width: 50, height: 50))
// size of your label
複製代碼
與以前不一樣,圖層不用渲染兩次。如今 GPU 有了足夠的信息繪製陰影效果, 就不用離屏渲染了。
對於文字陰影,用 NSShadow ,用 layer.path 就比較難。
過去,Core Animation 模版幾個調試選項很是強大,正常的綠色, 異常的紅色,離屏渲染的黃色。
(光柵化有效,光柵化後緩存的內容成功複用。界面會顯示綠色。
光柵化失效的部分,呈紅色。光柵化後緩存的內容沒有複用,光柵化隱式建立的位圖浪費了。直接從新繪製。 )
如今這些利器都在 Xcode 裏了,能夠直接使用。
真機運行直接選擇,
本文 Demo 使用的是 500 px 的 API .
Color Offscreen-Rendered Yellow
選項。調試目標是,出現大片的綠色。
這裏能夠用 Apple 的 UIKit 框架下的 NSShadow 對象。
let shadow = NSShadow()
shadow.shadowColor = UIColor.lightGray
shadow.shadowOffset = CGSize(width: 0.0, height: 5.0)
shadow.shadowBlurRadius = 5.0
if let mutableAttributedString = label.attributedText as? NSMutableAttributedString{
let range = NSRange(location: 0, length: mutableAttributedString.string.count)
mutableAttributedString.addAttribute(NSAttributedString.Key.shadow, value: shadow, range: range)
}
複製代碼
界面圖層混色,就是多個視圖的位置有重疊,他們又不是透明的。重疊區域的每個像素,GPU 須要算出一種新的顏色(混色)。 若是這種效果,不是 UI 設計的,儘可能避免。
Color Blended Layer
選項。override func awakeFromNib() {
super.awakeFromNib()
[userNameLabel, photosLikeLabel, photosDescriptionLabel, photoTimeIntevalSincePostLabel].forEach {
$0?.backgroundColor = UIColor.white
}
}
複製代碼
設置後, 效果明顯
混色,若是不是 UI 指定的效果,建議處理掉。
Instruments 的 Core Animation 模版的時間線,就是 FPS. 顯示隨着時間,App 的幀率波動。
能夠方便的讀取幀數,直觀的瞭解那些界面要改善。
用代碼檢測卡頓,天然是 CADisplayLink ,網上相關博客不少。