- 畫線的一些部分使用CALayer而不是UIView。
如果你使用CALayer,不設(shè)置contents,而是設(shè)置background color, Core Animation不會上傳任何數(shù)據(jù)給GPU,當(dāng)然這些工作還是要被GPU運算的,只是不需要具體的像素數(shù)據(jù),同理,漸變也是一個道理,不需要把像素上傳給GPU。
- 視圖位置能不調(diào)整就不要調(diào)整,在復(fù)雜的頁面盡量不使用autoLayout,因為cpu會一直在那計算位置
- 不要多次移除添加視圖,應(yīng)提前創(chuàng)建好,不需要的視圖暫時隱藏就好。
- 使用離屏渲染
self.layer.shouldRasterize(光柵化) = YES; //把原本離屏渲染的操作轉(zhuǎn)嫁到 CPU 上去,離屏渲染原本是在GPU上執(zhí)行的
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
你可能希望強制離屏渲染,特別是計算很復(fù)雜的時候。這是一種緩存合成好的紋理或是層的方式。如果你的呈現(xiàn)樹(render tree)是復(fù)雜的。那么就希望強制離屏渲染到緩存這些層,然后再使用緩存合成到屏幕。
如果你的APP有很多層,而且希望增加動畫。GPU一般來說不得不重新合成所有的層在1秒60幀的速度下。當(dāng)使用離屏渲染時,GPU需要合成這些層到一個新的位圖紋理緩存里面,然后再用這個紋理繪制到屏幕上面。當(dāng)這些層一起移動時,GPU可以重復(fù)利用這個位圖緩存,這樣就可以提高效率。當(dāng)然,如果這些層沒有修改的化,才能有效。如果這些層被修改了,GPU就不得不重新創(chuàng)建這個位圖緩存。你可以觸發(fā)這個行為,通過設(shè)置shouldRasterize = YES
這是一個權(quán)衡,如果只是繪制一次,那么這樣做反而會更慢。創(chuàng)建一個額外的緩存對GPU來說是一個額外的工作,特別是如果這個位圖永遠沒有被復(fù)用。這個實在是太浪費了。然而,如果這個位圖緩存可以被重用,GPU也可能把緩存刪掉了。所以你需要計算GPU的利用率和幀的速率來判斷這個位圖是否有用
離屏渲染也可以在一些其他場景發(fā)生。如果你直接或是間接的給一個層增加了遮罩。Core Animation 會為了實現(xiàn)遮罩強制做離屏渲染。這個增加了GPU的負擔(dān),因為一般上來,這些都是直接在屏幕上面渲染的。
Instrument的Core Animation 有一個叫做Color Offscreen-Rendered Yellow的選項。它會將已經(jīng)被渲染到屏幕外緩沖區(qū)的區(qū)域標注為黃色(這個選項在模擬器中也可以用)。同時確保勾選Color Hits Green and Misses Red選項。綠色代表無論何時一個屏幕外緩沖區(qū)被復(fù)用,而紅色代表當(dāng)緩沖區(qū)被重新創(chuàng)建。
一般來說,你需要避免離屏渲染。因為這個開銷很大。在屏幕上面直接合成層要比先創(chuàng)建一個離屏緩存然后在緩存上面繪制,最后再繪制緩存到屏幕上面快很多。這里面有2個上下文環(huán)境的切換(切換到屏幕外緩存環(huán)境,和屏幕環(huán)境)。
所以當(dāng)你打開Color Offscreen-Rendered Yellow后看到黃色,這便是一個警告,但這不一定是不好的。如果Core Animation能夠復(fù)用屏幕外渲染的結(jié)果,這便能夠提升性能,當(dāng)繪制到緩存上面的層沒有被修改的時候,就可以被復(fù)用了。
注意,緩存位圖的尺寸大小是有限制的。Apple 提示大約是2倍屏幕的大小。
如果你使用的層引發(fā)了離屏渲染,那么你最好避免這種方式。增加遮罩,設(shè)置圓角,設(shè)置陰影都造成離屏渲染。
對于遮罩來說,圓角只是一個特殊的遮罩。clipsToBounds 和 masksToBounds 2個屬性而已。你可以簡單的創(chuàng)建一個已經(jīng)設(shè)置好遮罩的層創(chuàng)建內(nèi)容。比如,使用已經(jīng)設(shè)置了遮罩的圖片。當(dāng)然,這個也是一種權(quán)衡。如果你希望在層的contents屬性這只一個矩形的遮罩,那你更應(yīng)該使用contentsRect而不是使用遮罩。
如果你最后還是shouldRasterize = YES,記住還要設(shè)置rasterizationScale = contentsScale
- 可變大小的圖片
通過拉伸圖片用比較小的圖片就可以了。
-[UIImage resizableImageWithCapInsets:resizingMode:]