UIView的繪制原理及優(yōu)化

UI卡頓&掉幀的原因

一般頁面滑動的幀數(shù)在60fps以內(nèi)時椿猎,頁面才會流暢,也就是說每一秒內(nèi)有60次的畫面更新残拐,相當(dāng)于在每隔16.7ms產(chǎn)生一幀畫面晾咪,在16.7ms內(nèi) CPUGPU 要完成一幀畫面的繪制與渲染。

圖片顯示
  • 正常顯示:

比如說 CPU 要在一定時間內(nèi)完成視圖的文本的布局鞋既、視圖的繪制以及圖片的解碼等工作力九,最終將位圖 (bitmap) 提交給 GPU ,然后 GPU 完成視圖的渲染邑闺,最終在16.7ms內(nèi)提交給視頻控制器顯示在屏幕上跌前。

圖片掉幀
  • 掉幀

如果說 CPU 在16.7ms內(nèi)占用的時間過多,最終導(dǎo)致 GPU 在16.7ms以后才將圖片渲染完提交給視頻控制器陡舅,就會導(dǎo)致掉幀舒萎,UI界面的卡頓

UIView的繪制原理

UIView的繪制原理

當(dāng)調(diào)用 UIView\color{red}{setNeedsDisplay} 方法時并不會立即繪制視圖,它會先調(diào)用視圖所對應(yīng)的的 layer 的同名方法 \color{red}{setNeedsDisplay} 方法蹭沛,相當(dāng)于在當(dāng)前視圖上打上了個臟標(biāo)記臂寝,然后在當(dāng)前 runloop 將要結(jié)束時調(diào)用 CALyer\color{red}{display} 方法,最后才會進入繪制流程當(dāng)中摊灭。
在調(diào)用 CALyer\color{red}{display} 方法時咆贬,首先會先判斷是否響應(yīng) layer\color{red}{displayLayer} 代理方法,如果不響應(yīng)則進入系統(tǒng)繪制流程帚呼,當(dāng)響應(yīng)時掏缎,則進入異步繪制入口。

系統(tǒng)繪制流程

系統(tǒng)繪制流程圖
  • CALayer 會回先創(chuàng)建一個 backing storeCGContextRef) 的上下文煤杀,然后會在 drawRect 方法中會在上下文堆棧中拿到 backing store
  • 判斷是否 CALayer 是否有代理
  • 如果沒有代理眷蜈,則調(diào)用系統(tǒng)的 \color{red}{drawInContext:} 方法
  • 如果有代理,則會調(diào)用 layer.delegate\color{red}{drawLayer:inContext:} 方法沈自,該方法發(fā)生自系統(tǒng)內(nèi)部酌儒,最后在合適的時機會調(diào)用 \color{red}{[UIView drawRect:]} 方法,該方法默認是什么都不做的
  • 最后都會將 backing store (位圖)上傳至GPU中枯途,最后結(jié)束繪制

異步繪制

- [layer.delegate displayerLayer:]
  • 代理負責(zé)生成對應(yīng)的bitmap
  • 設(shè)置該bitmap作為layer.contents屬性的值
異步繪制時序圖
  • 假如說在某個時間調(diào)用 \color{red}{setNeedsDisplay} 方法
  • 然后在當(dāng)前 runloop 將要結(jié)束的時候忌怎,會由系統(tǒng)調(diào)用視圖所對應(yīng)的 \color{red}{CALyer display} 方法,如果我們的 delegate 方法實現(xiàn)了 \color{red}{displayerLayer} 方法酪夷,則由系統(tǒng)調(diào)用該方法
  • 然后會通過子線程的切換榴啸,在子線程中實現(xiàn)視圖的繪制
  • 在子線程中創(chuàng)建位圖的上下文(\color{red}{- CGBitmapContextCreate()}),然后做UI的繪制工作(\color{red}{CoreGraphic 的 API})晚岭,然后根據(jù)繪制的上下文生成一張 CGImage 圖片(\color{red}{- CGBitmapContextCreateImage()}
  • 最后回到主隊列中鸥印,將該 CGImage 圖片設(shè)置為 CALayercontents

離屏渲染

  • 在屏渲染(On-Screen Rendering)

指的是 \color{red}{GPU} 的渲染操作是在用于當(dāng)前屏幕顯示的緩沖區(qū)中進行的

  • 離屏渲染(Off-Screen Rendering)

指的是 \color{red}{GPU} 在當(dāng)前屏幕緩沖區(qū)以外開辟一個 \color{red}{新的緩沖區(qū)} 進行渲染操作

  • 離屏渲染何時觸發(fā)

1、設(shè)置圓角(同時設(shè)置maskToBounds時才會觸發(fā))
2、設(shè)置視圖的圖層蒙版
3库说、設(shè)置陰影
4狂鞋、設(shè)置光柵化

  • 為何要避免離屏渲染

離屏渲染會導(dǎo)致 GPU 增加額外的開銷,會導(dǎo)致在CPU和GPU處理的視圖的總時長增加璃弄,超過16.7ms要销,可能會導(dǎo)致視圖的卡頓和掉幀

滑動優(yōu)化方案

  • CPU:

1构回、對象的創(chuàng)建夏块、調(diào)整、銷毀
2纤掸、預(yù)排版(布局計算脐供、文本計算等)
3、預(yù)渲染(文本的異步繪制借跪、圖片的編解碼等)

  • GPU:

1政己、避免離屏渲染
2、避免視圖混合(視圖層級太多)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掏愁,一起剝皮案震驚了整個濱河市歇由,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌果港,老刑警劉巖沦泌,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辛掠,居然都是意外死亡谢谦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門萝衩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來回挽,“玉大人,你說我怎么就攤上這事猩谊∏” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵牌捷,是天一觀的道長队塘。 經(jīng)常有香客問我,道長宜鸯,這世上最難降的妖魔是什么憔古? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮淋袖,結(jié)果婚禮上鸿市,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好焰情,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布陌凳。 她就那樣靜靜地躺著,像睡著了一般内舟。 火紅的嫁衣襯著肌膚如雪合敦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天验游,我揣著相機與錄音充岛,去河邊找鬼。 笑死耕蝉,一個胖子當(dāng)著我的面吹牛崔梗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垒在,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼蒜魄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了场躯?” 一聲冷哼從身側(cè)響起谈为,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎踢关,沒想到半個月后伞鲫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡耘成,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年榔昔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘪菌。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡撒会,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出师妙,到底是詐尸還是另有隱情诵肛,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布默穴,位于F島的核電站怔檩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蓄诽。R本人自食惡果不足惜薛训,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仑氛。 院中可真熱鬧乙埃,春花似錦闸英、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至遇伞,卻和暖如春辙喂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸠珠。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工巍耗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人跳芳。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓芍锦,卻偏偏與公主長得像竹勉,于是被迫代替她去往敵國和親飞盆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容