關於UI事件傳遞,影像顯示,效能優化,離屏渲染

小顧iOSer發表於2020-01-06

更多的文章請看-2020iOS面試大全 持續更新!

  • UIView與CALayer
  • 事件傳遞與檢視響應鏈
  • 影像顯示原理
  • UI卡頓掉幀原因
  • 滑動優化方案
  • UI繪製原理
  • 離屏渲染

一、UIView與CALayer

關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image

<單一職責原則>
UIView為CALayer提供內容,以及負責處理觸控等事件,參與響應鏈
CALayer負責顯示內容contents

二、事件傳遞與檢視響應鏈 :

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

複製程式碼
關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image
關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image

如果事件一直傳遞到UIAppliction還是沒處理,那就會忽略掉

三、影像顯示原理

關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image

1.CPU:輸出點陣圖
2.GPU :圖層渲染,紋理合成
3.把結果放到幀緩衝區(frame buffer)中
4.再由視訊控制器根據vsync訊號在指定時間之前去提取幀緩衝區的螢幕顯示內容
5.顯示到螢幕上

關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image

CPU工作

1.Layout: UI佈局,文字計算
2.Display: 繪製
3.Prepare: 圖片解碼
4.Commit:提交點陣圖

GPU渲染管線(OpenGL)

頂點著色,圖元裝配,光柵化,片段著色,片段處理

四、UI卡頓掉幀原因

關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image

iOS裝置的硬體時鐘會發出Vsync(垂直同步訊號),然後App的CPU會去計算螢幕要顯示的內容,之後將計算好的內容提交到GPU去渲染。隨後,GPU將渲染結果提交到幀緩衝區,等到下一個VSync到來時將緩衝區的幀顯示到螢幕上。也就是說,一幀的顯示是由CPU和GPU共同決定的。
一般來說,頁面滑動流暢是60fps,也就是1s有60幀更新,即每隔16.7ms就要產生一幀畫面,而如果CPU和GPU加起來的處理時間超過了16.7ms,就會造成掉幀甚至卡頓。

五、滑動優化方案
CPU:把以下操作放在子執行緒中
1.物件建立、調整、銷燬
2.預排版(佈局計算、文字計算、快取高度等等)
3.預渲染(文字等非同步繪製,圖片解碼等)

GPU:
紋理渲染,檢視混合

一般遇到效能問題時,考慮以下問題:
是否受到CPU或者GPU的限制?
是否有不必要的CPU渲染?
是否有太多的離屏渲染操作?
是否有太多的圖層混合操作?
是否有奇怪的圖片格式或者尺寸?
是否涉及到昂貴的view或者效果?
view的層次結構是否合理?

六、UI繪製原理

關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image
關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image

非同步繪製:

[self.layer.delegate displayLayer: ]
代理負責生成對應的bitmap
設定該bitmap作為該layer.contents屬性的值

關於UI事件傳遞,影像顯示,效能優化,離屏渲染
image

七、離屏渲染

On-Screen Rendering:當前螢幕渲染,指的是GPU的渲染操作是在當前用於顯示的螢幕緩衝區中進行
Off-Screen Rendering:離屏渲染,分為CPU離屏渲染和GPU離屏渲染兩種形式。GPU離屏渲染指的是GPU在當前螢幕緩衝區外新開闢一個緩衝區進行渲染操作
應當儘量避免的則是GPU離屏渲染

GPU離屏渲染何時會觸發呢?

圓角(當和maskToBounds一起使用時)、圖層蒙版、陰影,設定

layer.shouldRasterize = YES

複製程式碼

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

GPU需要做額外的渲染操作。通常GPU在做渲染的時候是很快的,但是涉及到offscreen-render的時候情況就可能有些不同,因為需要額外開闢一個新的緩衝區進行渲染,然後繪製到當前螢幕的過程需要做onscreen跟offscreen上下文之間的切換,這個過程的消耗會比較昂貴,涉及到OpenGL的pipeline跟barrier,而且offscreen-render在每一幀都會涉及到,因此處理不當肯定會對效能產生一定的影響。另外由於離屏渲染會增加GPU的工作量,可能會導致CPU+GPU的處理時間超出16.7ms,導致掉幀卡頓。所以可以的話應儘量減少offscreen-render的圖層

最後

作為一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流群:761407670 進群密碼000,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術, 大家一起交流學習成長!


文章地址-2020iOS面試大全


相關文章