1. 程式人生 > >一、Instrument之Core Animation工具

一、Instrument之Core Animation工具

上下 demo 正是 必須 相同 lock ask evel xcod

一、Instrument

三個方法:
(1)、按下Command + I打開Instrument;
(2)、Xcode->product->profile;
(3)、Xcode->Open Developer Tool->Instrument

二、Core Animation工具

1、界面

技術分享

2、簡單介紹

註意這個調試必須使用真機,點擊左上角的紅色圓圈就會開始錄制

技術分享

我們須要了解兩個兩個區域:
1、這裏記錄了實時的fps數值。有些地方是0是由於屏幕沒有滑動。
2、調試選項;

ps:有過遊戲經驗的人或許對fps這個概念比較熟悉。我們知道不論什麽屏幕總是有一個刷新率,比方iphone推薦的刷新率是60Hz,也就是說GPU每秒鐘刷新屏幕60次,因此兩次刷新之間的間隔為16.67ms。

這段時間內屏幕內容保持不變。稱為一幀(frame),fps表示frames per second,也就是每秒鐘顯示多少幀畫面。對於精巧不變的內容,我們不須要考慮它的刷新率。但在運行動畫或滑動時,fps的值直接反映出滑動的流暢程度。

三、調試、優化

1、Color Blended Layers

(1)、圖層混合

首先我們要明確像素的概念,屏幕上每一個點都是一個像素,像素有R、G、B三種顏色構成(有時候還帶有alpha值)。假設某一塊區域上覆蓋了多個layer,最後的顯示效果受到這些layer的共同影響。舉個樣例。上層是藍色(RGB=0,0,1),透明度為50%,下層是紅色(RGB=1,0,0)。那麽終於的顯示效果是紫色(RGB=0.5,0,0.5)。

這樣的顏色的混合(blending)須要消耗一定的GPU資源,由於實際上可能不止僅僅有兩層。

假設僅僅想顯示最上層的藍色,能夠把它的透明度設置為100%,這樣GPU會忽略以下全部的layer,從而節約了非常多不必要的運算。

(2)、調試Color Blended Layers

第一個調試選項”Color Blended Layers”正是用於檢測哪裏發生了圖層混合。並用紅色標記出來。

因此我們須要盡可能降低看到的紅色區域。

一旦發現應該想法設法消除它。開始調試後勾選這個選項,我們在手機上能夠看到例如以下的場景:
技術分享

重要的是backgroundColor屬性。假設不設置這個屬性。控件依舊被覺得是透明的。所以我們做的第一個優化是設置控件的backgroundColor屬性。

PS:假設label文字有中文,依舊會出現圖層混合,這是由於此時label多了一個sublayer。

2、Color Hits Green and Misses Red

(1)、光柵化

光柵化是將一個layer預先渲染成位圖(bitmap),然後加入緩存中。假設對於陰影效果這樣比較消耗資源的靜態內容進行緩存,能夠得到一定幅度的性能提升。demo中的這一行代碼表示將label的layer光柵化:

label.layer.shouldRasterize = YES;

(2)、調試Color Hits Green and Misses Red

第二個調試選項是“Color Hits Green and Misses Red”,它表示假設命中緩存則顯示為綠色,否則顯示為紅色,顯然綠色越多越好,紅色越少越好。

註意:光柵化的核心在於緩存的思想。我們自己動手把玩一下,能夠發現以下幾個有意思的現象:

上下微小幅度滑動時,一直是綠色
上下較大幅度滑動,新出現的label一開始是紅色,隨後變成綠色
假設精巧一秒鐘。剛開始滑動時會變紅。

這是由於layer進行光柵化後渲染成位圖放在緩存中。

當屏幕出現滑動時,我們直接從緩存中讀取而不必渲染,所以會看到綠色。當新的label出現時,緩存中沒有個這個label的位圖。所以會變成紅色。第三點比較關鍵,緩存中的對象有效期僅僅有100ms,即假設在0.1s內沒有被使用就會自己主動從緩存中清理出去。

這就是為什麽停留一會兒再滑動就會看到紅色。

光柵化的緩存機制是一把雙刃劍。先寫入緩存再讀取有可能消耗較多的時間。因此光柵化僅適用於較復雜的、靜態的效果。通過Instrument的調試發現。這裏使用光柵化常常出現未命中緩存的情況,假設沒有特殊須要則能夠關閉光柵化,所以我們做的第二個優化是凝視掉以下這行代碼

//    label.layer.shouldRasterize = true

3、Color Copied Images

(1)、顏色格式

像素在內存中的布局和它在磁盤中的存儲方式並不相同。考慮一種簡單的情況:每一個像素有R、G、B和alpha四個值。每一個值占用1字節。因此每一個像素占用4字節的內存空間。

一張1920*1080的照片(iPhone6 Plus的分辨率)一共同擁有2,073,600個像素。因此占用了超過8Mb的內存。可是一張相同分辨率的PNG格式或JPEG格式的圖片普通情況下不會有這麽大。這是由於JPEG將像素數據進行了一種非常復雜且可逆的轉化。

CPU主要處理兩件事:

(1)把圖片從PNG或JPEG等格式中解壓出來,得到像素數據
(2)假設GPU不支持這樣的顏色各式,CPU須要進行格式轉換

比方應用中有一些從網絡下載的圖片。而GPU恰好不支持這個格式。這就須要CPU預先進行格式轉化。

(2)、調試Color Copied Images

第三個選項“Color Copied Images”就用來檢測這樣的實時的格式轉化,假設有則會將圖片標記為藍色。

4、Color Misaligned Images

(1)、圖片大小

在項目中,我們網絡請求圖片。大小不一,可是展示的UIImageView有時候是固定大小。這時候我們就須要圖片的縮放了。圖片的縮放須要占用時間,因此我們要盡可能保證不管是本地圖片還是從網絡或取得圖片的大小,都與其frame保持一致。

(2)、調試Color Misaligned Images

第五個選項“Color Misaligned Images”,它表示假設圖片須要縮放則標記為黃色。假設沒有像素對齊則標記為紫色。勾選上這個選項並進行調試。能夠看到例如以下場景:

技術分享

5、Color Offscreen-Rendered Yellow

(1)、離屏渲染

離屏渲染表示渲染發生在屏幕之外。離屏渲染意味著把渲染結果暫時保存,等用到時再取出,因此相對於普通渲染更占用資源。

(2)、調試Color Offscreen-Rendered Yellow

第六個選項“Color Offscreen-Rendered Yellow”會把須要離屏渲染的地方標記為黃色,大部分情況下我們須要盡可能避免黃色的出現。

離屏渲染可能會自己主動觸發。也能夠手動觸發。以下情況可能會導致觸發離屏渲染:

1、重寫drawRect方法。(自己主動觸發離屏渲染)
2、有mask或者是陰影(layer.masksToBounds, layer.shadow*)。模糊效果也是一種mask。(自己主動觸發離屏渲染)
3、layer.shouldRasterize = true。(手動開啟離屏渲染)

開始調試並勾選“Color Offscreen-Rendered Yellow”。會看到這樣的場景:

技術分享

能夠看到tabbar和statusBar也是黃色,這是由於它們使用了模糊效果。
假設圖片使用了陰影,也是黃色,這說明它也進行了離屏渲染,解決方式。在設置陰影效果的四行代碼以下加入一行:

imgView.layer.shadowPath = UIBezierPath(rect: imgView.bounds).CGPath  

這行代碼制定了陰影路徑。假設沒有手動指定。Core Animation會去自己主動計算,這就會觸發離屏渲染。假設人為指定了陰影路徑。就能夠免去計算,從而避免產生離屏渲染。

設置cornerRadius本身並不會導致離屏渲染,但非常多時候它還須要配合layer.masksToBounds = true使用。依據之前的總結,設置masksToBounds會導致離屏渲染。

解決方式是盡可能在滑動時避免設置圓角,假設必須設置圓角,能夠使用光柵化技術將圓角緩存起來:

// 設置圓角
label.layer.masksToBounds = true  
label.layer.cornerRadius = 8  
label.layer.shouldRasterize = true  
label.layer.rasterizationScale = layer.contentsScale 

6、Color Compositing Fast-Path Blue

(1)、高速路徑

離屏渲染的最後一步是把此前的多個路徑組合起來。假設這個組合過程能由CPU完畢,就會大量降低GPU的工作。

這樣的技術在繪制地圖中可能用到。

(2)、調試Color Compositing Fast-Path Blue

第七個選項“Color Compositing Fast-Path Blue”用於標記由硬件繪制的路徑,藍色越多越好。

7、Flash updated Regions

(1)、變化區域

刷新視圖時,我們應該把須要重繪的區域盡可能縮小。

對於未發生變化的內容則不應該重繪。

(2)、調試Flash updated Regions

第八個選項“Flash updated Regions”用於標記發生重繪的區域。

四、總結

  • 1、避免圖層混合

    • ①、確保控件的opaque屬性設置為true。確保backgroundColor和父視圖顏色一致且不透明;
    • ②、如無特殊須要。不要設置低於1的alpha值;
    • ③、確保UIImage沒有alpha通道;
  • 2、避免暫時轉換

    • ①、確保圖片大小和frame一致,不要在滑動時縮放圖片。
    • ②、確保圖片顏色格式被GPU支持,避免勞煩CPU轉換;
  • 3、慎用離屏渲染

    • ①、絕大多數時候離屏渲染會影響性能;
    • ②、重寫drawRect方法。設置圓角、陰影、模糊效果,光柵化都會導致離屏渲染;
    • ③、設置陰影效果是加上陰影路徑。
    • ④、滑動時若須要圓角效果,開啟光柵化。

一、Instrument之Core Animation工具