UI相關(guān)復(fù)習(xí)(事件傳遞、圖像顯示、性能優(yōu)化、離屏渲染)

UI相關(guān)復(fù)習(xí)(事件傳遞、圖像顯示、性能優(yōu)化、離屏渲染)

UIView與CALayer

  1. UIView為CALayer提供內(nèi)容,處理觸摸事件,參與響應(yīng)鏈
  2. CALayer負(fù)責(zé)顯示內(nèi)容contents

事件傳遞與響應(yīng)鏈

開(kāi)始 -> UIApplication -> UIWindow -> hitTest:withEvent: -> pointInside:withEvent: -> Subviews -> 同級(jí)UIView -> 倒序遍歷

如果事件一直傳遞到UIAppliction還是沒(méi)處理,那就會(huì)忽略掉

圖像顯示原理

  1. CPU 輸出位圖
  2. GPU 圖層渲染、紋理合成
  3. 把結(jié)果放到幀緩沖區(qū)(frame buffer)中
  4. 再由視頻控制器根據(jù)vsync信號(hào)在指定時(shí)間之前去提取幀緩沖區(qū)的屏幕顯示內(nèi)容
  5. 顯示到屏幕上

CPU工作:

  1. Layout:UI布局、文本計(jì)算
  2. Display:繪制(drawRect:)
  3. Prepare:圖片解碼
  4. Commit:提交位圖

GPU渲染管線(openGL)

頂點(diǎn)著色,圖元裝配,光柵化,片段著色,片段處理

UI卡頓掉幀原因

iOS設(shè)備的硬件時(shí)鐘會(huì)發(fā)出vsync(垂直同步信號(hào)),然后APP的CPU會(huì)去計(jì)算屏幕要顯示的內(nèi)容,之后將計(jì)算好的內(nèi)容提交到GPU去渲染。隨后,GPU將渲染結(jié)果提交到幀緩沖區(qū),等到下一個(gè)vsync到來(lái)時(shí)將緩沖區(qū)的幀顯示到屏蔽上。也就是說(shuō),一幀的顯示是由CPU和GPU共同決定的。

一般來(lái)說(shuō),頁(yè)面滑動(dòng)流暢是60fps,也就是1秒60幀更新,即16.7ms產(chǎn)生一幀畫畫,如果CPU+GPU處理時(shí)長(zhǎng)超過(guò)這個(gè)時(shí)間長(zhǎng)就會(huì)造成掉幀甚至卡頓。

滑動(dòng)優(yōu)化方案

CPU:把以下操作放在子線程中

  1. 對(duì)象創(chuàng)建、調(diào)整、銷毀
  2. 預(yù)排版(布局計(jì)算、文本計(jì)算、緩存高度等)
  3. 預(yù)渲染(文本等異步繪制,圖片解碼等)

GPU:紋理渲染、視圖混合

遇到性能問(wèn)題時(shí),考慮以下幾個(gè)問(wèn)題:

  1. 是否受到CPU或者GPU限制
  2. ?是否有不必要的CPU渲染
  3. 是否有太多的離屏渲染
  4. 是否有太多的圖層混合操作
  5. 是否有奇怪的圖片格式或者尺寸
  6. 是否涉及到昂貴的view或者效果
  7. view的層次結(jié)構(gòu)是否合理

UI繪制原理

[UIView setNeedsDisplay]->[view.layer setNeedsDisplay]->[CALayer display]->layer.delegate respondsTo:@selector(displayLayer)-YES->異步繪制入口-NO->系統(tǒng)繪制流程 ->end

異步繪制

[self.layer.delegate displayLayer:]

代理負(fù)責(zé)生成對(duì)應(yīng)的bitmap

設(shè)置該bitmap作為layer.contents屬性的值

離屏渲染

On-Screen Rendering:當(dāng)前屏幕渲染,指的是GPU的渲染操作是在當(dāng)前用于顯示的屏幕緩沖區(qū)中進(jìn)行

Off-Screen Rendering:離屏渲染,分為CPU離屏渲染和GPU離屏渲染兩種形式。GPU離屏渲染指的是GPU在當(dāng)前屏幕緩沖區(qū)外新開(kāi)辟一個(gè)緩沖區(qū)進(jìn)行渲染操作

應(yīng)當(dāng)盡量避免的帽是GPU離屏渲染

GPU離屏渲染何時(shí)會(huì)觸發(fā)?

圓角(當(dāng)和maskToBounds一起使用時(shí))、圖層蒙版、陰影,設(shè)置

layer.shouldRasterize = YES;

為什么要避免GPU離屏渲染?

GPU需要做額外的渲染操作。通常GPU在做渲染的時(shí)候是很快的,但是涉及到off-Screen rendering的時(shí)候情況就可能有些不同,因?yàn)樾枰~外開(kāi)辟一個(gè)新的緩沖區(qū)進(jìn)行渲染,然后繪制到當(dāng)前屏幕的過(guò)程需要on screenoff screen上下文之間的切換,這個(gè)過(guò)程的消耗會(huì)比較昂貴,涉及到OpenGLpipelinebarrier,而且off-screen-render在每一幀都會(huì)涉及到,因此處理不當(dāng)肯定會(huì)對(duì)性能產(chǎn)生一定的影響。另外由于離屏渲染會(huì)增加GPU的工作量,可能會(huì)導(dǎo)致CPU+GPU的處理時(shí)間超出16.7,導(dǎo)致掉幀卡頓。所以可以的話應(yīng)盡量減少off-screen-render的圖層

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容