在第一和第二部分,我們了解了Core Animation
提供的關(guān)于繪制和動(dòng)畫的一些特 性。Core Animation
功能和性能都非常強(qiáng)大,但如果你對(duì)背后的原理不清楚的話也會(huì)降低效率。讓它達(dá)到最優(yōu)的狀態(tài)是一門藝術(shù)。在這章中,我們將探究一些動(dòng)畫運(yùn) 行慢的原因,以及如何去修復(fù)這些問(wèn)題。
CPU VS GPU
關(guān)于繪圖和動(dòng)畫有兩種處理的方式:CPU(中央處理器)
和GPU(圖形處理器)
。在現(xiàn)代iOS
設(shè)備中,都有可以運(yùn)行不同軟件的可編程芯片,但是由于歷史原因,我們可以說(shuō)CPU所做的工作都在軟件層面,而GPU在硬件層面。
總的來(lái)說(shuō),我們可以用軟件(使用CPU
)做任何事情,但是對(duì)于圖像處理,通常用硬件會(huì)更快,因?yàn)?code>GPU使用圖像對(duì)高度并行浮點(diǎn)運(yùn)算做了優(yōu)化。由于某些原因, 我們想盡可能把屏幕渲染的工作交給硬件去處理。問(wèn)題在于GPU
并沒(méi)有無(wú)限制處理 性能,而且一旦資源用完的話,性能就會(huì)開(kāi)始下降了(即使CPU
并沒(méi)有完全占用)
大多數(shù)動(dòng)畫性能優(yōu)化都是關(guān)于智能利用GPU
和CPU
,使得它們都不會(huì)超出負(fù)荷。 于是我們首先需要知道Core Animation
是如何在這兩個(gè)處理器之間分配工作的。
動(dòng)畫的舞臺(tái)
Core Animation
處在iOS
的核心地位:應(yīng)用內(nèi)和應(yīng)用間都會(huì)用到它。一個(gè)簡(jiǎn)單的 動(dòng)畫可能同步顯示多個(gè)app
的內(nèi)容,例如當(dāng)在iPad
上多個(gè)程序之間使用手勢(shì)切換, 會(huì)使得多個(gè)程序同時(shí)顯示在屏幕上。在一個(gè)特定的應(yīng)用中用代碼實(shí)現(xiàn)它是沒(méi)有意義 的,因?yàn)樵?code>iOS中不可能實(shí)現(xiàn)這種效果(App
都是被沙箱管理,不能訪問(wèn)別的視 圖)。
動(dòng)畫和屏幕上組合的圖層實(shí)際上被一個(gè)單獨(dú)的進(jìn)程管理,而不是你的應(yīng)用程序。 這個(gè)進(jìn)程就是所謂的渲染服務(wù)。在iOS5
和之前的版本是SpringBoard
進(jìn)程(同時(shí)管 理著iOS
的主屏)。在iOS6
之后的版本中叫做 BackBoard
。
當(dāng)運(yùn)行一段動(dòng)畫時(shí)候,這個(gè)過(guò)程會(huì)被四個(gè)分離的階段被打破:
布局 - 這是準(zhǔn)備你的視圖/圖層的層級(jí)關(guān)系,以及設(shè)置圖層屬性(位置,背景色,邊框等等)的階段。
顯示 - 這是圖層的寄宿圖片被繪制的階段。繪制有可能涉及你的
- drawRect:
和-drawLayer:inContext:
方法的調(diào)用路徑。準(zhǔn)備 - 這是
Core Animation
準(zhǔn)備發(fā)送動(dòng)畫數(shù)據(jù)到渲染服務(wù)的階段。這同時(shí)也是Core Animation
將要執(zhí)行一些別的事務(wù)例如解碼動(dòng)畫過(guò)程中將要顯示的圖片的 時(shí)間點(diǎn)。提交 - 這是最后的階段,
Core Animation
打包所有圖層和動(dòng)畫屬性,然后通過(guò)IPC
(內(nèi)部處理通信)發(fā)送到渲染服務(wù)進(jìn)行顯示。
但是這些階段僅僅發(fā)生在你的應(yīng)用程序之內(nèi),在動(dòng)畫在屏幕上顯示之前仍然 有更多的工作。一旦打包的圖層和動(dòng)畫到達(dá)渲染服務(wù)進(jìn)程,他們會(huì)被反序列化來(lái)形成另一個(gè)叫做渲染樹的圖層樹(在第一章“圖層樹”中提到過(guò))。使用這個(gè)樹狀結(jié)構(gòu),渲染服務(wù)對(duì)動(dòng)畫的每一幀做出如下工作:
- 對(duì)所有的圖層屬性計(jì)算中間值,設(shè)置
OpenGL
幾何形狀(紋理化的三角形)來(lái)執(zhí)行渲染 - 在屏幕上渲染可見(jiàn)的三角形
所以一共有六個(gè)階段
;最后兩個(gè)階段在動(dòng)畫過(guò)程中不停地重復(fù)。前五個(gè)階段都在軟件層面處理(通過(guò)CPU
),只有最后一個(gè)被GPU
執(zhí)行。而且,你真正只能控制前 兩個(gè)階段:布局和顯示。Core Animation
框架在內(nèi)部處理剩下的事務(wù),你也控制不 了它。
這并不是個(gè)問(wèn)題,因?yàn)樵诓季趾惋@示階段,你可以決定哪些由CPU
執(zhí)行,哪些交給GPU
去做。那么改如何判斷呢?
GPU相關(guān)的操作
GPU
為一個(gè)具體的任務(wù)做了優(yōu)化:它用來(lái)采集圖片和形狀(三角形),運(yùn)行變換,應(yīng)用紋理和混合然后把它們輸送到屏幕上?,F(xiàn)代iOS
設(shè)備上可編程的GPU
在這些操作的執(zhí)行上又很大的靈活性,但是Core Animation
并沒(méi)有暴露出直接的接口。 除非你想繞開(kāi)Core Animation
并編寫你自己的OpenGL
著色器,從根本上解決硬件加速的問(wèn)題,那么剩下的所有都還是需要在CPU
的軟件層面上完成。
寬泛的說(shuō),大多數(shù) CALayer
的屬性都是用GPU
來(lái)繪制。比如如果你設(shè)置圖層背景或者邊框的顏色,那么這些可以通過(guò)著色的三角板實(shí)時(shí)繪制出來(lái)。如果對(duì)一個(gè) contents
屬性設(shè)置一張圖片,然后裁剪它 - 它就會(huì)被紋理的三角形繪制出來(lái), 而不需要軟件層面做任何繪制。
但是有一些事情會(huì)降低(基于GPU)圖層繪制,比如:
太多的幾何結(jié)構(gòu) - 這發(fā)生在需要太多的三角板來(lái)做變換,以應(yīng)對(duì)處理器的柵格 化的時(shí)候。現(xiàn)代
iOS
設(shè)備的圖形芯片可以處理幾百萬(wàn)個(gè)三角板,所以在Core Animation
中幾何結(jié)構(gòu)并不是GPU
的瓶頸所在。但由于圖層在顯示之前通過(guò)IPC
發(fā)送到渲染服務(wù)器的時(shí)候(圖層實(shí)際上是由很多小物體組成的特別重量級(jí)的對(duì) 象),太多的圖層就會(huì)引起CPU
的瓶頸。這就限制了一次展示的圖層個(gè)數(shù)(見(jiàn)本章后續(xù)“CPU相關(guān)操作”
)。重繪 - 主要由重疊的半透明圖層引起。
GPU
的填充比率(用顏色填充像素的比率)是有限的,所以需要避免重繪(每一幀用相同的像素填充多次)的發(fā)生。 在現(xiàn)代iOS
設(shè)備上,GPU
都會(huì)應(yīng)對(duì)重繪;即使是iPhone 3GS
都可以處理高達(dá)2.5
的重繪比率,并仍然保持60
幀率的渲染(這意味著你可以繪制一個(gè)半的整屏的冗余信息,而不影響性能),并且新設(shè)備可以處理更多。離屏繪制 - 這發(fā)生在當(dāng)不能直接在屏幕上繪制,并且必須繪制到離屏圖片的上下文中的時(shí)候。離屏繪制發(fā)生在基于
CPU
或者是GPU
的渲染,或者是為離屏圖 片分配額外內(nèi)存,以及切換繪制上下文,這些都會(huì)降低GPU
性能。對(duì)于特定圖層效果的使用,比如圓角,圖層遮罩,陰影或者是圖層光柵化都會(huì)強(qiáng)制Core Animation
提前渲染圖層的離屏繪制。但這不意味著你需要避免使用這些效 果,只是要明白這會(huì)帶來(lái)性能的負(fù)面影響。過(guò)大的圖片 - 如果視圖繪制超出
GPU
支持的2048x2048
或者4096x4096
尺寸的紋理,就必須要用CPU
在圖層每次顯示之前對(duì)圖片預(yù)處理,同樣也會(huì)降低性能。
CPU相關(guān)的操作
大多數(shù)工作在Core Animation
的CPU
都發(fā)生在動(dòng)畫開(kāi)始之前。這意味著它不會(huì)影響到幀率,所以很好,但是他會(huì)延遲動(dòng)畫開(kāi)始的時(shí)間,讓你的界面看起來(lái)會(huì)比較遲鈍。
以下CPU
的操作都會(huì)延遲動(dòng)畫的開(kāi)始時(shí)間:
布局計(jì)算 - 如果你的視圖層級(jí)過(guò)于復(fù)雜,當(dāng)視圖呈現(xiàn)或者修改的時(shí)候,計(jì)算圖層幀率就會(huì)消耗一部分時(shí)間。特別是使用
iOS6
的自動(dòng)布局機(jī)制尤為明顯,它應(yīng)該是比老版的自動(dòng)調(diào)整邏輯加強(qiáng)了CPU
的工作。視圖懶加載 -
iOS
只會(huì)當(dāng)視圖控制器的視圖顯示到屏幕上時(shí)才會(huì)加載它。這對(duì) 內(nèi)存使用和程序啟動(dòng)時(shí)間很有好處,但是當(dāng)呈現(xiàn)到屏幕上之前,按下按鈕導(dǎo)致 的許多工作都會(huì)不能被及時(shí)響應(yīng)。比如控制器從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù),或者視圖 從一個(gè)nib
文件中加載,或者涉及IO
的圖片顯示(見(jiàn)后續(xù)“IO相關(guān)操作”
),都會(huì)比CPU
正常操作慢得多。
-
Core Graphics
繪制 - 如果對(duì)視圖實(shí)現(xiàn)了- drawRect:
方法,或者CALayerDelegate
的- drawLayer:inContext:
方法,那么在繪制任何東西之前都會(huì)產(chǎn)生一個(gè)巨大的性能開(kāi)銷。為了支持對(duì)圖層內(nèi)容的任意繪制,Core Animation
必須創(chuàng)建一個(gè)內(nèi)存中等大小的寄宿圖片。然后一旦繪制結(jié)束之后, 必須把圖片數(shù)據(jù)通過(guò)IPC
傳到渲染服務(wù)器。在此基礎(chǔ)上,Core Graphics
繪制就 會(huì)變得十分緩慢,所以在一個(gè)對(duì)性能十分挑剔的場(chǎng)景下這樣做十分不好。
- 解壓圖片 -
PNG
或者JPEG
壓縮之后的圖片文件會(huì)比同質(zhì)量的位圖小得多。但是在圖片繪制到屏幕上之前,必須把它擴(kuò)展成完整的未解壓的尺寸(通常等同于圖片寬 x 長(zhǎng) x 4個(gè)字節(jié)
)。為了節(jié)省內(nèi)存,iOS
通常直到真正繪制的時(shí)候才去解碼圖片(14章“圖片IO”會(huì)更詳細(xì)討論
)。根據(jù)你加載圖片的方式,第一次對(duì)圖層內(nèi)容賦值的時(shí)候(直接或者間接使用UIImageView
)或者把它繪制到Core Graphics
中,都需要對(duì)它解壓,這樣的話,對(duì)于一個(gè)較大的圖片,都會(huì) 占用一定的時(shí)間。
當(dāng)圖層被成功打包,發(fā)送到渲染服務(wù)器之后,CPU
仍然要做如下工作:為了顯示 屏幕上的圖層,Core Animation
必須對(duì)渲染樹種的每個(gè)可見(jiàn)圖層通過(guò)OpenGL
循環(huán)轉(zhuǎn)換成紋理三角板。由于GPU
并不知曉Core Animation
圖層的任何結(jié)構(gòu),所以必須 要由CPU
做這些事情。這里CPU
涉及的工作和圖層個(gè)數(shù)成正比,所以如果在你的層 級(jí)關(guān)系中有太多的圖層,就會(huì)導(dǎo)致CPU
沒(méi)一幀的渲染,即使這些事情不是你的應(yīng)用 程序可控的。
IO相關(guān)操作
還有一項(xiàng)沒(méi)涉及的就是IO
相關(guān)工作。上下文中的IO
(輸入/輸出)指的是例如閃存或者網(wǎng)絡(luò)接口的硬件訪問(wèn)。一些動(dòng)畫可能需要從閃存(甚至是遠(yuǎn)程URL
)來(lái)加 載。一個(gè)典型的例子就是兩個(gè)視圖控制器之間的過(guò)渡效果,這就需要從一個(gè)nib
文件 或者是它的內(nèi)容中懶加載,或者一個(gè)旋轉(zhuǎn)的圖片,可能在內(nèi)存中尺寸太大,需要?jiǎng)?態(tài)滾動(dòng)來(lái)加載。
IO
比內(nèi)存訪問(wèn)更慢,所以如果動(dòng)畫涉及到IO
,就是一個(gè)大問(wèn)題。總的來(lái)說(shuō),這就需要使用聰敏但尷尬的技術(shù),也就是多線程,緩存和投機(jī)加載(提前加載當(dāng)前不需 要的資源,但是之后可能需要用到)。這些技術(shù)將會(huì)在第14章中討論。
測(cè)量,而不是猜測(cè)
于是現(xiàn)在你知道有哪些點(diǎn)可能會(huì)影響動(dòng)畫性能,那該如何修復(fù)呢?好吧,其實(shí)不需要。有很多種詭計(jì)來(lái)優(yōu)化動(dòng)畫,但如果盲目使用的話,可能會(huì)造成更多性能上的問(wèn)題,而不是修復(fù)。
如何正確的測(cè)量而不是猜測(cè)這點(diǎn)很重要。根據(jù)性能相關(guān)的知識(shí)寫出代碼不同于倉(cāng)促的優(yōu)化。前者很好,后者實(shí)際上就是在浪費(fèi)時(shí)間。
那該如何測(cè)量呢?第一步就是確保在真實(shí)環(huán)境下測(cè)試你的程序。
真機(jī)測(cè)試,而不是模擬器
當(dāng)你開(kāi)始做一些性能方面的工作時(shí),一定要在真機(jī)上測(cè)試,而不是模擬器。模擬器雖然是加快開(kāi)發(fā)效率的一把利器,但它不能提供準(zhǔn)確的真機(jī)性能參數(shù)。
模擬器運(yùn)行在你的Mac
上,然而Mac
上的CPU
往往比iOS
設(shè)備要快。相反,Mac
上的GPU
和iOS
設(shè)備的完全不一樣,模擬器不得已要在軟件層面(CPU
)模擬設(shè)備 的GPU
,這意味著GPU
相關(guān)的操作在模擬器上運(yùn)行的更慢,尤其是使用 CAEAGLLayer
來(lái)寫一些OpenGL
的代碼時(shí)候。
這就是說(shuō)在模擬器上的測(cè)試出的性能會(huì)高度失真。如果動(dòng)畫在模擬器上運(yùn)行流暢,可能在真機(jī)上十分糟糕。如果在模擬器上運(yùn)行的很卡,也可能在真機(jī)上很平滑。你無(wú)法確定。
另一件重要的事情就是性能測(cè)試一定要用發(fā)布配置,而不是調(diào)試模式。因?yàn)楫?dāng)用 發(fā)布環(huán)境打包的時(shí)候,編譯器會(huì)引入一系列提高性能的優(yōu)化,例如去掉調(diào)試符號(hào)或 者移除并重新組織代碼。你也可以自己做到這些,例如在發(fā)布環(huán)境禁用NSLog語(yǔ) 句。你只關(guān)心發(fā)布性能,那才是你需要測(cè)試的點(diǎn)。
最后,最好在你支持的設(shè)備中性能最差的設(shè)備上測(cè)試:如果基于iOS6
開(kāi)發(fā),這意 味著最好在iPhone 3GS
或者iPad2
上測(cè)試。如果可能的話,測(cè)試不同的設(shè)備和iOS
版本,因?yàn)樘O果在不同的iOS
版本和設(shè)備中做了一些改變,這也可能影響到一些性 能。例如iPad3
明顯要在動(dòng)畫渲染上比iPad2
慢很多,因?yàn)殇秩?code>4倍多的像素點(diǎn)(為 了支持視網(wǎng)膜顯示)。
保持一致的幀率
為了做到動(dòng)畫的平滑,你需要以60FPS
(幀每秒)的速度運(yùn)行,以同步屏幕刷新 速率。通過(guò)基于 NSTimer
或者 CADisplayLink
的動(dòng)畫你可以降低到30FPS
,而且效果還不錯(cuò),但是沒(méi)辦法通過(guò)Core Animation
做到這點(diǎn)。如果不保持60FPS
的速 率,就可能隨機(jī)丟幀,影響到體驗(yàn)。
你可以在使用的過(guò)程中明顯感到有沒(méi)有丟幀,但沒(méi)辦法通過(guò)肉眼來(lái)得到具體的數(shù)據(jù),也沒(méi)法知道你的做法有沒(méi)有真的提高性能。你需要的是一系列精確的數(shù)據(jù)。
你可以在程序中用 CADisplayLink
來(lái)測(cè)量幀率(就像11章“基于定時(shí)器的動(dòng)畫”
中那樣),然后在屏幕上顯示出來(lái),但應(yīng)用內(nèi)的FPS
顯示并不能夠完全真實(shí)測(cè)量出Core Animation
性能,因?yàn)樗鼉H僅測(cè)出應(yīng)用內(nèi)的幀率。我們知道很多動(dòng)畫都在應(yīng) 用之外發(fā)生(在渲染服務(wù)器進(jìn)程中處理),但同時(shí)應(yīng)用內(nèi)FPS
計(jì)數(shù)的確可以對(duì)某些 性能問(wèn)題提供參考,一旦找出一個(gè)問(wèn)題的地方,你就需要得到更多精確詳細(xì)的數(shù)據(jù) 來(lái)定位到問(wèn)題所在。蘋果提供了一個(gè)強(qiáng)大的Instruments
工具集來(lái)幫我們做到這些。
Instruments
Instruments
是Xcode
套件中沒(méi)有被充分利用的一個(gè)工具。很多iOS
開(kāi)發(fā)者從沒(méi)用過(guò)Instruments
,或者只是用Leaks
工具檢測(cè)循環(huán)引用。實(shí)際上有很多Instruments
工 具,包括為動(dòng)畫性能調(diào)優(yōu)的東西。
你可以通過(guò)在菜單中選擇Profile
選項(xiàng)來(lái)打開(kāi)Instruments
(在這之前,記住要把目標(biāo)設(shè)置成iOS
設(shè)備,而不是模擬器)。然后將會(huì)顯示出圖12.1(如果沒(méi)有看到所有 選項(xiàng),你可能設(shè)置成了模擬器選項(xiàng))。
我們將討論如下幾個(gè)工具:
- 時(shí)間分析器 - 用來(lái)測(cè)量被方法/函數(shù)打斷的
CPU
使用情況。 - Core Animation - 用來(lái)調(diào)試各種
Core Animation
性能問(wèn)題。 - OpenGL ES驅(qū)動(dòng) - 用來(lái)調(diào)試
GPU
性能問(wèn)題。這個(gè)工具在編寫Open GL
代碼的時(shí)候很有用,但有時(shí)也用來(lái)處理Core Animation
的工作。
時(shí)間分析器
時(shí)間分析器工具用來(lái)檢測(cè)CPU
的使用情況。它可以告訴我們程序中的哪個(gè)方法正在消耗大量的CPU
時(shí)間。使用大量的CPU
并不一定是個(gè)問(wèn)題 - 你可能期望動(dòng)畫路徑對(duì)CPU
非常依賴,因?yàn)閯?dòng)畫往往是iOS
設(shè)備中最苛刻的任務(wù)。
但是如果你有性能問(wèn)題,查看CPU
時(shí)間對(duì)于判斷性能是不是和CPU
相關(guān),以及定位到函數(shù)都很有幫助。
時(shí)間分析器有一些選項(xiàng)來(lái)幫助我們定位到我們關(guān)心的的方法。可以使用左側(cè)的復(fù)選框來(lái)打開(kāi)。其中最有用的是如下幾點(diǎn):
- 通過(guò)線程分離 - 這可以通過(guò)執(zhí)行的線程進(jìn)行分組。如果代碼被多線程分離的話,那么就可以判斷到底是哪個(gè)線程造成了問(wèn)題。
- 隱藏系統(tǒng)庫(kù) - 可以隱藏所有蘋果的框架代碼,來(lái)幫助我們尋找哪一段代碼造成 了性能瓶頸。由于我們不能優(yōu)化框架方法,所以這對(duì)定位到我們能實(shí)際修復(fù)的 代碼很有用。
- 只顯示
Obj-C
代碼 - 隱藏除了Objective-C
之外的所有代碼。大多數(shù)內(nèi)部的Core Animation
代碼都是用C
或者C++
函數(shù),所以這對(duì)我們集中精力到我們代碼中顯 式調(diào)用的方法就很有用。
Core Animation
Core Animation
工具用來(lái)監(jiān)測(cè)Core Animation
性能。它給我們提供了周期性的 FPS
,并且考慮到了發(fā)生在程序之外的動(dòng)畫。
Core Animation
工具也提供了一系列復(fù)選框選項(xiàng)來(lái)幫助調(diào)試渲染瓶頸:
-
Color Blended Layers
- 這個(gè)選項(xiàng)基于渲染程度對(duì)屏幕中的混合區(qū)域進(jìn)行綠到 紅的高亮(也就是多個(gè)半透明圖層的疊加)。由于重繪的原因,混合對(duì)GPU
性能會(huì)有影響,同時(shí)也是滑動(dòng)或者動(dòng)畫幀率下降的罪魁禍?zhǔn)字弧?/li> -
ColorHitsGreenandMissesRed
- 當(dāng)使用shouldRasterizep
屬性的時(shí)候, 耗時(shí)的圖層繪制會(huì)被緩存,然后當(dāng)做一個(gè)簡(jiǎn)單的扁平圖片呈現(xiàn)。當(dāng)緩存再生的 時(shí)候這個(gè)選項(xiàng)就用紅色對(duì)柵格化圖層進(jìn)行了高亮。如果緩存頻繁再生的話,就 意味著柵格化可能會(huì)有負(fù)面的性能影響了(更多關(guān)于使用shouldRasterize
的細(xì)節(jié)見(jiàn)第15章“圖層性能”
)。 -
Color Copied Images
- 有時(shí)候寄宿圖片的生成意味著Core Animation被強(qiáng)制 生成一些圖片,然后發(fā)送到渲染服務(wù)器,而不是簡(jiǎn)單的指向原始指針。這個(gè)選 項(xiàng)把這些圖片渲染成藍(lán)色。復(fù)制圖片對(duì)內(nèi)存和CPU使用來(lái)說(shuō)都是一項(xiàng)非常昂貴 的操作,所以應(yīng)該盡可能的避免。
Color Immediately
- 通常Core Animation Instruments
以每毫秒10
次的頻率更新圖層調(diào)試顏色。對(duì)某些效果來(lái)說(shuō),這顯然太慢了。這個(gè)選項(xiàng)就可以用來(lái)設(shè)置 每幀都更新(可能會(huì)影響到渲染性能,而且會(huì)導(dǎo)致幀率測(cè)量不準(zhǔn),所以不要一 直都設(shè)置它)。__Color Misaligned Images
__ - 這里會(huì)高亮那些被縮放或者拉伸以及沒(méi)有正確對(duì) 齊到像素邊界的圖片(也就是非整型坐標(biāo))。這些中的大多數(shù)通常都會(huì)導(dǎo)致圖片的不正常縮放,如果把一張大圖當(dāng)縮略圖顯示,或者不正確地模糊圖像,那么這個(gè)選項(xiàng)將會(huì)幫你識(shí)別出問(wèn)題所在。
-
Color Offscreen-Rendered Yellow
- 這里會(huì)把那些需要離屏渲染的圖層高亮 成黃色。這些圖層很可能需要用shadowPath
或者shouldRasterize
來(lái)優(yōu) 化。
Color OpenGL Fast Path Blue
- 這個(gè)選項(xiàng)會(huì)對(duì)任何直接使用OpenGL
繪制的 圖層進(jìn)行高亮。如果僅僅使用UIKit
或者Core Animation
的API
,那么不會(huì)有任何效果。如果使用GLKView
或者CAEAGLLayer
,那如果不顯示藍(lán)色塊的話 就意味著你正在強(qiáng)制CPU
渲染額外的紋理,而不是繪制到屏幕。Flash Updated Regions
- 這個(gè)選項(xiàng)會(huì)對(duì)重繪的內(nèi)容高亮成黃色(也就是任何 在軟件層面使用Core Graphics
繪制的圖層)。這種繪圖的速度很慢。如果頻繁發(fā)生這種情況的話,這意味著有一個(gè)隱藏的bug
或者說(shuō)通過(guò)增加緩存或者使用替代方案會(huì)有提升性能的空間。
這些高亮圖層的選項(xiàng)同樣在iOS模擬器的調(diào)試菜單也可用(下圖)。我們之前 說(shuō)過(guò)用模擬器測(cè)試性能并不好,但如果你能通過(guò)這些高亮選項(xiàng)識(shí)別出性能問(wèn)題出在 什么地方的話,那么使用iOS模擬器來(lái)驗(yàn)證問(wèn)題是否解決也是比真機(jī)測(cè)試更有效 的。
OpenGL ES驅(qū)動(dòng)
OpenGL ES
驅(qū)動(dòng)工具可以幫你測(cè)量GPU
的利用率,同樣也是一個(gè)很好的來(lái)判斷和GPU
相關(guān)動(dòng)畫性能的指示器。它同樣也提供了類似Core Animation
那樣顯示FPS
的工具。
其中和Core Animation
性能最相關(guān)的是如下幾 點(diǎn):
-
Renderer Utilization
- 如果這個(gè)值超過(guò)了~50%
,就意味著你的動(dòng)畫可能對(duì)幀率有所限制,很可能因?yàn)殡x屏渲染或者是重繪導(dǎo)致的過(guò)度混合。 -
Tiler Utilization
- 如果這個(gè)值超過(guò)了~50%
,就意味著你的動(dòng)畫可能限制于幾何結(jié)構(gòu)方面,也就是在屏幕上有太多的圖層占用了。
總結(jié)
在這章中,我們學(xué)習(xí)了Core Animation
是如何渲染,以及我們可能出現(xiàn)的瓶頸所在。你同樣學(xué)習(xí)了如何使用Instruments
來(lái)檢測(cè)和修復(fù)性能問(wèn)題。