小心別讓圓角成了你列表的幀數殺手

2021-07-04 10:07:29 字數 2613 閱讀 2680

在ios的世界,圓角無處不在,而且必須存在。因為圓角是符合人類視覺安全體驗的,圓角讓人覺得舒適,而方角在潛意識層次是具有傷害體驗的,因為尖尖的東西總是有可能對人造成傷害的,所以我們更喜歡圓角。在我之前的文章中講過,在ios的中設定圓角是非常容易的一件事情,這也體現出蘋果也是非常重視圓角這件事情的。

圓角雖好,但如果使用不當,它就是你的幀數殺手,特別當它出現在滾動列表的時候。下面來看圓角如何毀掉你的流暢度的。

layer.cornerradius

我建立了乙個簡單地uitableview檢視,為每個cell新增了2個uiimageview例項,且為uiimageview例項進行如下設定

aimageview.layer

.cornerradius = aimageview.frame

.size

.width/2.0

; aimageview.layer

.maskstobounds = yes;

執行截圖如下:

你們猜,現在滾動的幀率是多少。

已經跌至45幀每秒,這個幀率已經讓人感覺到不那麼順滑了,如果低於40幀每秒,普通使用者就會察覺明顯的不流暢了。當我把cell的uiimageview例項增加至四個

現在幀率已經低於30幀每秒了

平均幀率提高了大概3幀每秒。

在這裡檢視和圓角的大小對幀率並沒有什麼卵影響,數量才是傷害的核心輸出啊。

layer.mask

cashapelayer *layer = [cashapelayer layer];  

uibezierpath *apath = [uibezierpath bezierpathwithovalinrect:aimageview.bounds];

layer.path = apath.cgpath

; aimageview.layer

.mask = layer;

得到的幀率如下:

竟然只有20幀每秒了,比layer.cornerradius還少了8幀!!!所以layer.cornerradius實現圓角的效能是要比layer.mask要高很多。

maskview

ios的uiview多了乙個maskview方法,不過這個東西和layer.mask是乙個卵樣的。

上面拖慢幀率的原因其實都是off-screen rendering(離屏渲染)的原因。離屏渲染是個好東西,但是頻繁發生離屏渲染是非常耗時的。

off-screen rendering

離屏渲染,指的是gpu在當前螢幕緩衝區以外新開闢乙個緩衝區進行渲染操作。由上面的乙個結論檢視和圓角的大小對幀率並沒有什麼卵影響,數量才是傷害的核心輸出啊。可以知道離屏渲染耗時是發生在離屏這個動作上面,而不是渲染。為什麼離屏這麼耗時?原因主要有建立緩衝區上下文切換。建立新的緩衝區代價都不算大,付出最大代價的是上下文切換。

上下文切換

上下文切換,不管是在gpu渲染過程中,還是一直所熟悉的程序切換,上下文切換在**都是乙個相當耗時的操作。首先我要儲存當前螢幕渲染環境,然後切換到乙個新的繪製環境,申請繪製資源,初始化環境,然後開始乙個繪製,繪製完畢後銷毀這個繪製環境,如需要切換到on-screen rendering或者再開始乙個新的離屏渲染重複之前的操作。 下圖描述了一次mask的渲染操作。

一次mask發生了兩次離屏渲染和一次主屏渲染。即使忽略昂貴的上下文切換,一次mask需要渲染三次才能在螢幕上顯示,這已經是普通檢視顯示3陪耗時,若再加上下文環境切換,一次mask就是普通渲染的30倍以上耗時操作。問我這個30倍以上這個資料怎麼的出來的?當我在cell的uiimageview的例項增加到150個,並去掉圓角的時候,幀數才跌至28幀每秒。雖然不是甚準確,但至少反映mask這個耗時是無mask操作的耗時的數十倍的。

那麼如何應對這個問題呢?不要在滾動檢視使用cornerradius或者mask。如果你非要作死怎麼辦呢?那麼這樣也可以拯救你:

self.layer

.shouldrasterize = yes;

self.layer

.rasterizationscale = [uiscreen mainscreen].scale

;

這樣大部分情況下可以馬上挽救你的幀數在55幀每秒以上。shouldrasterize = yes會使檢視渲染內容被快取起來,下次繪製的時候可以直接顯示快取,當然要在檢視內容不改變的情況下。

除了上面非要作死的人外,大家還是採取預先生成圓角,並快取起來這個方法才是比較好的手段。預處理圓角可以在後台處理,處理完畢後快取起來,再在主線程顯示,這就避免了不必要的離屏渲染了。

另外也有在上面覆蓋乙個鏤空圓形的方法可以實現圓形頭像效果,這個也是極為高效的方法。缺點就是對檢視的背景有要求,單色背景效果就最為理想。

實現圓角cornerradius要比mask高效很多。

rasterize在大部分情況下極大減少gpu工作。在有空間的情況下,大部分情況下快取總能幫到你,不是嗎?

後台預處理也能很簡單幫上你很大的忙。

(以上測試資料來自於iphone5。)

別讓惰性控制你

偶然看到一句很貼近生活的話 別人都在你看不到的地方暗自努力,在你看得到的地方,他們也和你一樣顯得吊兒郎當,和你一樣會抱怨,而只有你自己相信這些都是真的,最後也只有你一人繼續不思進取。很多句子總在不經意中就會戳中一部分人的軟肋,我想我們每個人的周圍總是有那麼些表現得 吊兒郎當 的存在,是否你就真的相信...

小心eMule出賣你

小心emule 出賣你 emule 電驢 是乙個完全免費而且開放源 的 p2p軟體,正因為完全免費所以在中非常普及,大家都非常喜歡使用它交換網路資源。但是,當我們充分享受軟體帶給我們網路互聯的好處的同時,也不能忽視它的安全性,最近也暴露出該軟體的漏洞問題。漏洞形成的原因 一般的軟體安全問題都是由於在...

站長 別讓「H1」成了你K站的罪魁禍首

今天在 優化站長群裡,有個新來的站長問我,可不可以在 logo後面的那句話加個h1標籤,作為 優化專員的我給他發了個笑臉,不錯哦,能有這樣的覺悟的確很不容易,h1標籤的用處便是讓權重集中在加了h1的關鍵詞中,能迅速提公升權重,不過接著我跟他說,你在這個地方加了 h1 這也許就是以後你的 被k的 罪魁...