【iOS】介面優化
本文是在前人總結的基礎上進行高度概括,簡單介紹造成介面卡頓的原因和解決思路。
螢幕成像原理
![2280423-b50222e2974e36cb.png](https://i.iter01.com/images/d87805e3b6e6715da4526f0948e909d7e8b78202abc0873847216af5365342cd.png)
首先從過去的 CRT 顯示器原理說起。CRT 的電子槍按照上面方式,從上到下一行行掃描,掃描完成後顯示器就呈現一幀畫面,隨後電子槍回到初始位置繼續下一次掃描。為了把顯示器的顯示過程和系統的視訊控制器進行同步,顯示器(或者其他硬體)會用硬體時鐘產生一系列的定時訊號。當電子槍換到新的一行,準備進行掃描時,顯示器會發出一個水平同步訊號(horizonal synchronization),簡稱 HSync;而當一幀畫面繪製完成後,電子槍回覆到原位,準備畫下一幀前,顯示器會發出一個垂直同步訊號(vertical synchronization),簡稱 VSync。顯示器通常以固定頻率進行重新整理,這個重新整理率就是 VSync 訊號產生的頻率。儘管現在的裝置大都是液晶螢幕了,但原理仍然沒有變。
![2280423-0443182a8a94db88.png](https://i.iter01.com/images/d25de7b765d3a05aa9ce354ac8500965f8ee6d19f7f033fd2d277648f9ddf453.png)
通常來說,計算機系統中 CPU、GPU、顯示器是以上面這種方式協同工作的。CPU 計算好顯示內容提交到 GPU,GPU 渲染完成後將渲染結果放入幀緩衝區,隨後視訊控制器會按照 VSync 訊號逐行讀取幀緩衝區的資料,經過可能的數模轉換傳遞給顯示器顯示。
在最簡單的情況下,幀緩衝區只有一個,這時幀緩衝區的讀取和重新整理都都會有比較大的效率問題。為了解決效率問題,顯示系統通常會引入兩個緩衝區,即雙緩衝機制。在這種情況下,GPU 會預先渲染好一幀放入一個緩衝區內,讓視訊控制器讀取,當下一幀渲染好後,GPU 會直接把視訊控制器的指標指向第二個緩衝器。如此一來效率會有很大的提升。
雙緩衝雖然能解決效率問題,但會引入一個新的問題。當視訊控制器還未讀取完成時,即螢幕內容剛顯示一半時,GPU 將新的一幀內容提交到幀緩衝區並把兩個緩衝區進行交換後,視訊控制器就會把新的一幀資料的下半段顯示到螢幕上,造成畫面撕裂現象,如下圖:
![2280423-592a4d7a978afda2.jpg](https://i.iter01.com/images/2d1973e6d1941c23673f07d120de9efe040823cda4948d6e92913545d4e3cb86.jpg)
為了解決這個問題,GPU 通常有一個機制叫做垂直同步(簡寫也是 V-Sync),當開啟垂直同步後,GPU 會等待顯示器的 VSync 訊號發出後,才進行新的一幀渲染和緩衝區更新。這樣能解決畫面撕裂現象,也增加了畫面流暢度,但需要消費更多的計算資源,也會帶來部分延遲。
那麼目前主流的移動裝置是什麼情況呢?從網上查到的資料可以知道,iOS 裝置會始終使用雙快取,並開啟垂直同步。而安卓裝置直到 4.1 版本,Google 才開始引入這種機制,目前安卓系統是三快取+垂直同步。
卡頓產生的原因和解決方案
![2280423-2f14d85702118855.png](https://i.iter01.com/images/3780994bb19c288097f99ec66234ac32609bbedc1cd86cbcf9a22b8ff1e8f210.png)
在 VSync 訊號到來後,系統圖形服務會通過 CADisplayLink 等機制通知 App,App 主執行緒開始在 CPU 中計算顯示內容,比如檢視的建立、佈局計算、圖片解碼、文字繪製等。隨後 CPU 會將計算好的內容提交到 GPU 去,由 GPU 進行變換、合成、渲染。隨後 GPU 會把渲染結果提交到幀緩衝區去,等待下一次 VSync 訊號到來時顯示到螢幕上。由於垂直同步的機制,如果在一個 VSync 時間內,CPU 或者 GPU 沒有完成內容提交,則那一幀就會被丟棄,等待下一次機會再顯示,而這時螢幕會保留之前的內容不變。這就是介面卡頓的原因。
從上面的圖中可以看到,CPU 和 GPU 不論哪個阻礙了顯示流程,都會造成掉幀現象。所以開發時,也需要分別對 CPU 和 GPU 壓力進行評估和優化。
綜上所述,實際專案中,一般可以將佈局資訊提前計算好並快取,滑動tableview的時候儘量減少cpu計算佈局資訊的使用。
更多優化方法請移步
iOS 保持介面流暢的技巧
相關文章
- iOS 介面效能優化淺析iOS優化
- iOS 效能優化思路:介面離屏渲染、圖層混色iOS優化
- iOS 效能優化套路iOS優化
- IOS效能優化篇iOS優化
- iOS啟動優化iOS優化
- iOS效能優化 - APP啟動時間優化iOS優化APP
- iOS 圖形效能優化iOS優化
- ios效能優化相關iOS優化
- iOS 效能優化備忘iOS優化
- iOS 效能優化的探索iOS優化
- iOS 效能優化總結iOS優化
- iOS Flexbox 佈局優化iOSFlex優化
- iOS效能優化 - 網路圖片載入優化iOS優化
- iOS首頁渲染優化 -- imageName:iOS優化
- 【iOS 印象】效能優化梳理(Swift)iOS優化Swift
- iOS-效能優化深入探究iOS優化
- iOS冒泡演算法優化iOS演算法優化
- iOS效能優化系列篇之“列表流暢度優化”iOS優化
- iOS效能優化系列篇之“優化總體原則”iOS優化
- iOS效能優化 - 工具Instruments之CoreAnimationiOS優化
- iOS圖片記憶體優化iOS記憶體優化
- iOS 效能篇一一UITableView效能優化iOSUIView優化
- 使用 Go 優化我們的介面Go優化
- 記一次介面效能優化實踐總結:優化介面效能的八個建議優化
- iOS 使用Instruments優化記憶體效能iOS優化記憶體
- iOS中responseToSelector()方法是不是需要優化iOS優化
- iOS效能優化 - 工具Instruments之Time ProfileriOS優化
- iOS問題整理08----效能優化iOS優化
- iOS網路層詳解和優化iOS優化
- iOS 啟動速度優化和安裝包優化簡單總結iOS優化
- Java介面全鏈路優化:如何降低介面RT時長Java優化
- 漫漫優化路,總會錯幾步(記一次介面優化)優化
- C# Winform程式介面優化例項C#ORM優化
- iOS拾遺—— Assets Catalogs 與 I/O 優化iOS優化
- iOS效能優化之頁面載入速率iOS優化
- 對於iOS效能優化的一點看法iOS優化
- ? python 介面自動化 (一)-- 什麼是介面、介面優勢、型別 (詳解)Python型別
- Python如何優化列表介面進行分頁Python優化
- iOS App優化1---減少包體積iOSAPP優化