如此高強度的項目壓力下茅信,爭取一個月寫一篇吧屹徘。之后估計會出一個基礎(chǔ)補完系列捍靠,爭取一個星期更一篇沐旨。此文章只是用來記錄自己的學(xué)習(xí)過程,如有錯誤歡迎指正榨婆。
概述
在iOS中隨處可見各種列表磁携,如聊天列表,評論列表良风,視頻列表等谊迄。用高端機跑一些內(nèi)容簡單的列表是不會感覺到任何的卡頓的。但在低端機上面烟央,大廠和小作坊的列表流暢度的差距就顯現(xiàn)出來了统诺,優(yōu)秀的代碼在低端機上允許也如同高端機一樣絲滑。
卡頓產(chǎn)生的原因
你可以理解為系統(tǒng)會定時向App發(fā)送一個信號疑俭,在顯示之前粮呢,App主線程會在CPU中計算顯示內(nèi)容,比如視圖的創(chuàng)建、布局計算啄寡、圖片解碼豪硅、文本繪制等。隨后 CPU 會將計算好的內(nèi)容提交到 GPU 去挺物,由 GPU 進行變換懒浮、合成、渲染姻乓。隨后 GPU 會把渲染結(jié)果提交到幀緩沖區(qū)去嵌溢,當(dāng)信號到來的時候,如果幀緩沖區(qū)沒有東西蹋岩,根據(jù)垂直同步,這一幀會被丟棄学少,等待下一次機會再顯示剪个,而這時屏幕會顯示與之前相同的內(nèi)容,從而造成了視覺上的卡頓版确。
那么無論是CPU還是GPU出現(xiàn)了問題 只要最終的結(jié)果沒有渲染完成就會造成界面卡頓扣囊。所以開發(fā)的時候要同事兼顧CPU和GPU。
優(yōu)化方案
既然知道CPU和GPU都有造成卡頓的可能绒疗,那么優(yōu)化方案都是針對于CPU和GPU 減少計算時間侵歇,不讓某一時間計算量暴增,避免一方爆炸一方很閑的情況吓蘑,這些優(yōu)化方案都是可行的惕虑。CPU消耗時間主要在:對象創(chuàng)建、對象調(diào)整磨镶、對象銷毀溃蔫、布局計算、自動布局琳猫、文本計算伟叛、圖片的解碼。GPU耗時主要在:紋理的渲染脐嫂、視圖的混合 统刮、圖形的生成。針對這幾個方面進行優(yōu)化账千,能大大提高列表的流暢度侥蒙。
避免離屏渲染
在iOS中離屏渲染好像被提及的比較多,其原理可以百度蕊爵,因為我也是百度知道的辉哥,我就不CV了,簡而言之就是GPU新開辟了一塊內(nèi)存供CPU渲染,這是一種時間換空間的策略醋旦。離屏渲染的整個過程恒水,需要多次切換上下文環(huán)境;等到離屏渲染結(jié)束以后饲齐,將離屏緩沖區(qū)的渲染結(jié)果顯示到屏幕上有需要將上下文環(huán)境從離屏切換到當(dāng)前屏幕钉凌。而上下文環(huán)境的切換是要付出很大代價的。
如何避免離屏渲染
- 避免設(shè)置layer的mask layer.mask
- 避免設(shè)置圖層的投影 layer.shadow
- 圖層的光柵化layer.ShouldRasterize
- 圖層不為一層時 layer.maskToBounds = true
預(yù)排版
當(dāng)我們從接口取得數(shù)據(jù)時捂人,我們就應(yīng)該計算出顯示內(nèi)容所需的高度并存儲起來御雕,視圖布局的計算是CPU最耗時的地方,多次對frame滥搭、bounds進行調(diào)整非常消耗資源酸纲,因此,提前計算好最終布局瑟匆,然后一次調(diào)整闽坡,而不是頻繁調(diào)整這些屬性。自動布局也是在顯示前計算愁溜,而不是提前計算完成疾嗅,對于復(fù)雜視圖來說常常會產(chǎn)生嚴(yán)重的性能問題。
避免圖層混合
我們開發(fā)中為了實現(xiàn)某種效果冕象,常將圖層像畫布一樣一層層疊起來代承,這樣GPU需要一層層繪制,消耗了大量資源渐扮,為了減少GPU資源消耗论悴,應(yīng)將多層圖層合成一層來顯示,并適當(dāng)?shù)臏p少視圖層數(shù)和和數(shù)量席爽,并在不透明的視圖中標(biāo)明opaque屬性以避免無用的Alpha通道合成意荤。比如如果UIlabel的背景為純色的話,應(yīng)該給UIlabel設(shè)置背景色來避免圖層混合只锻。
更高效的異步圖片加載
優(yōu)秀的異步加載圖片庫 SDWebImage 已經(jīng)可以滿足大部分需求了玖像,將圖片全部存在內(nèi)存中并加上動畫可以避免異步加載時圖片閃白。另外注意在顯示圖片的時候要避免圖片被拉伸或被壓縮齐饮,這在一定程度上也會造成性能的消耗捐寥。
寫在后面的話
所有的優(yōu)化都是為了提高CPU和GPU的計算速度的,所謂的優(yōu)化就是在壓榨硬件性能祖驱,但是硬件性能也有極限握恳。產(chǎn)品總不可能讓你在黑白電視上播彩色電影吧。