iOS顯示性能優化過程講解

點我跳轉原文地址

logo.png

卡頓的原理

iOS系統界面滑動流暢性的保持主要是依靠CPU和GPU兩大處理硬件間通力合作的結果,一個視圖的顯示需要先經過CPU創建、布局計算、對圖片解碼、文本繪制,然后CPU將計算的結果交給GPU,GPU可能需要對圖形進行變換、合成、渲染,GPU然后將渲染的結果提交到幀緩沖區等待下一次的垂直同步信號(V-Sync)到來顯示到顯示器上,如果在一個V-Sync間隔內CPU或者GPU由于過高的利用率都可能導致數據的不及時提交,那么那一幀數據就會被丟棄,等待下一次的V-Sync再顯示,這也就是通常能感受到的界面卡頓現象,也就是掉幀。

優化過程

所以當出現卡頓現象時主要去分析此刻CPU和GPU的利用率,當出現較高的CPU利用率時應及時去分析代碼執行的效率,或者用Time Profier去分析導致較高占用率的代碼,更多詳細的關于優化CPU的情況本文不做詳細分析。
而對于GPU資源消耗的優化本文將通過一個Demo優化過程來講解優化的步驟,你可以在這里GitHub下載源碼,Demo是有2個tab組成的,before是優化前視圖,after是優化后的,你可以通過對比學習體會其中的差異。
下載運行demo, 打開Xcode的調試選項,在菜單欄-Debug-View Debugging-Rendering可以找到,運行APP(真機)勾選相關的菜單選項即可
Rendering.png

1.視圖混合(Blending)

app中顯示的效果往往是多個視圖重合疊加的效果,而在計算視圖重合顯示顏色的時候就需要考慮透明的影響,當頂部視圖出現透明的情況時,顏色的計算就需要考慮其透明度,這樣無疑增加了計算成本,消耗GPU資源,所以應盡量避免過多的透明視圖數量。
對于UIImageView而言,如果圖片本身是帶有透明通道的同樣會導致Blending,所以應該盡量避免使用帶有透明度的圖片。
對于文本UILable, 如果不設置背景顏色,同樣會出現Blending,所以需要設置UILabel的背景顏色,對于顯示中文的UILabel, 除了設置背景顏色外還需要設置masksToBounds屬性,因為中文時UILable會多了一個sublayer。
勾選Rendering中的第一個選項Color Blended Layers,此選項就是用于檢測哪些視圖出現了Blending,出現Blending的地方會用紅色標記出來,運行demo可以出現下圖所示情況:
Blending.png

可以看到,before tab下的控制器視圖無論是圖片還是文本都被標紅,表示出現了Blending,對于圖片我們可以在Assets里面找到對應的圖片,然后查看簡介就可以查看圖片是否有Alpha通道,會看到圖片都具有Alpha通道,也就回導致Blending
Alpha通道.png
對于這種情況,可以讓UI切圖時關閉此Alpha通道,也可以直接用mac自帶的圖片軟件打開圖片,然后導出圖片關閉Alpha通道。所以我們需要將所有有Alpha的圖片都處理一遍,盡量不要使用帶有透明度的圖片。
對于UILabel,上面有提到,我們只需要下面的2行代碼即可處理:

titleLabel.backgroundColor = UIColor.white
titleLabel.layer.masksToBounds = true

通過去掉圖片alpha通道優化后如下圖所示,只有被設置為圓角的小圖片還存在Blending,因為我們是直接設置的layer的cornerRadius(IOS9以下會導致離屏渲染),同樣我們可以直接用無透明通道的圓角圖片來替換解決,但這需要UI適配更多背景圖片。
Blending優化后.png

2.光柵化

開啟光柵化是通過設置屬性shouldRasterize,開啟光柵化后CALayer會被保存為bitmap放到緩存中,這樣在下次需要時可以直接中緩存中取出來顯示,這樣節省了渲染時間,例如對于設置有陰影效果的復雜視圖會對性能有一定的提升。

nameLabel.layer.shouldRasterize = true//開啟光柵化

第二個調試選項 Color Hits Green and Misses Red就是用來查看光柵化視圖的,勾選后若視圖被標記為綠色,則表示命中了緩存,直接從緩存中取出來顯示,緩存的有效時間為100ms, 而紅色則表示沒有命中。Demo中,我們對第2個Label開啟了光柵化,滾動會發現被標記為綠色
光柵化.png

更新一個已光柵化的Layer會觸發離屏渲染,所以選擇哪些視圖適合做光柵化需要根據場景權衡,光柵化適合那些布局復雜而不經常變動的視圖,比如

  • 用于避免靜態內容的復雜特效的重繪,例如UIBlurEffect
  • 用于避免多個View嵌套的復雜View的重繪。

同時注意緩存是有大小限制的,所以不要過度是使用光柵化,因為超過緩存大小會導致大量的離屏渲染。

3.顏色格式

Color Copied Images選項能標識出視圖中不能被GPU處理的圖片,因為來自網絡的圖片格式可能千變萬化,有的圖片的格式是GPU無法識別的所以會交給CPU處理,出現這種情況就需要修改圖片格式,

4.不標準的表面顏色格式

Color Non-Standard Surface Formats 打開此選項后會發現Label會出現灰色的背景顏色,然后經過我們給Label設置了背景顏色后便消失了,關于此選項的相關介紹甚少,期待有人能挖掘挖掘,所以只能猜測,蘋果推薦我們給Label設置一個背景顏色。
Non-Standard.png

5.顏色刷新頻率

默認情況下圖層的顏色更新是有10ms的延遲的,在某些特定情況下可能需要關閉這個延遲,但絕大多數情況用不到這個選項。

6.圖片大小

Color Misaligned Images選項在圖片像素不對齊(也就是圖片帶alpha通道)時,會在圖片上面加一層洋紅色來標識;而圖片被縮放時,會加一層黃色來標識,我們可以看到優化前的圖片會出現圖片縮放,因為圖片的顯示大小和圖片的大小不匹配。
Misaligned.png
圖片縮放同樣會消耗GPU資源,所以盡量保證圖片的顯示大小和原圖大小一致來避免縮放,所以demo的圖片在處理后大小都等于顯示的大小來避免縮放。

7.離屏渲染

Color Offscreen-Rendered Yellow會用黃色標識哪些圖層出現了離屏渲染,什么是離屏渲染?
離屏渲染表示渲染不是發生在當前屏幕的緩沖區中,而是發生在其他緩沖區的渲染,這就需要開辟更多的緩沖區,等到要用的時候再從其他的緩沖區讀取來顯示,所以這樣會消耗更多的GPU資源,所以避免離屏渲染可以有效的提升顯示性能。
離屏渲染.png
如上圖所示,要顯示一個相機圖標和一個蒙層,在前兩個渲染通道中,GPU分別得到了相機的紋理和藍色的蒙版layer的渲染結果。但這兩個渲染結果沒有直接放入Frame Buffer中,這就是離屏渲染。等到第三個渲染通道,才把兩者組合起來放入Frame Buffer中最終顯示到屏幕上,這就是典型的離屏渲染。
運行demo,打開Color Offscreen-Rendered Yellow選項,在beforetab控制器視圖下出現離屏渲染的圖層便會被黃色標識出來,如圖:
Offscreen.png
可以發現右邊的大圖出現了離屏渲染,而圓角的小圖卻沒有,大圖出現離屏渲染的原因是設置了shadow陰影,而因為測試機器是ios11所以設置圖片的cornerRadius并不會導致離屏渲染。
同樣設置了以下屬性時,都會觸發離屏渲染:

  • shouldRasterize(光柵化)
  • masks(遮罩)
  • shadows(陰影)
  • edge antialiasing(抗鋸齒)
  • group opacity(不透明)
  • 復雜形狀設置圓角等(ios8)
  • 漸變

上面出現離屏渲染的case都應該要注意,所以針對shadow可以通過設置shadowPath來避免,光柵化也應該盡量避免:
優化后代碼如下:

        mainImageView.layer.shadowColor = UIColor.black.cgColormainImageView.layer.shadowOpacity = 1mainImageView.layer.shadowRadius = 2
//        mainImageView.layer.shadowOffset = CGSize(width: 2, height: 2)mainImageView.layer.shadowPath = UIBezierPath.init(roundedRect: mainImageView.bounds, cornerRadius: 2).cgPathsmallImageView.layer.cornerRadius = smallImageView.frame.size.width / 2smallImageView.clipsToBounds = truenameLabel.backgroundColor = UIColor.whitetitleLabel.backgroundColor = UIColor.whitetitleLabel.layer.masksToBounds = truenameLabel.layer.masksToBounds = true
//        nameLabel.layer.shouldRasterize = true

8.快速路徑

第七個選項“Color Compositing Fast-Path Blue”用于標記由硬件繪制的路徑,藍色越多越好,demo略

9.變化區域

最后一個Flash Updated Regions 用于標記發生重繪制的區域并用黃色標記出來,對于大多數不變的區域應該盡量的避免重繪而只有小部分經常變化的區域重繪這有助于顯著提高性能。demo略

優化結果

經過對圖片Alpha透明度調整,大小剪裁適配顯示,更改設置陰影,文本背景等一系列的優化,使用Core Animation記錄GPU使用率的變化來觀察優化效果:
before:
before.png
可以看到優化前CPU平均占用率達到60%,這還只是簡單的視圖布局,如果更加復雜占用率還會增加,這也就意味著更高的卡頓風險。

after:
after.png

對比可以發現在提升了平均顯示幀數的同時大大降低了GPU消耗,性能得到顯著的提升。

測試環境:Xcode9.3、iPhone6s、 iOS11、Swift4
Demo地址:GitHub地址

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/254511.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/254511.shtml
英文地址,請注明出處:http://en.pswp.cn/news/254511.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

asp.net web api集成微信服務(使用Senparc微信SDK)

/// <summary>/// 微信請求轉發控制器/// </summary>[RoutePrefix("weixin")]public class WeixinController : ApiController{#region 創建微信菜單/// <summary>/// 創建微信菜單/// </summary>/// <returns></returns>[HttpP…

1.SoapUI接口測試--創建項目

1、點擊File-->New soapUI Project 2、填寫項目名稱&#xff0c;接口服務地址后單擊【OK】按鈕后就成功創建了一個項目 3、模擬發送請求 4、創建請求 或者直接Copy一個請求 5、保存項目 6、項目是以xml的格式保存的&#xff0c;下次用的時候可以直接導入&#xff0c;點擊Fil…

Misc混合halcon算子,持續更新

目錄convol_imageexpand_domain_graygray_insidegray_skeletonlut_transsymmetrytopographic_sketchdeviation_nconvol_image 功能&#xff1a;用一個任意濾波掩碼對一個圖像卷積。 expand_domain_gray 功能&#xff1a;擴大圖像區域并且在擴大的區域中設置灰度值。 gray_i…

C/C++ 函數指針調用函數

01//C/C 函數指針調用函數 02#include<iostream> 03using namespace std; 04 05void site1() 06{ 07 cout<<"www.ok2002.com"<<endl; 08} 09 10void site2() 11{ 12 cout<<"www.ok1700.com"<<endl; 13} 14 15void…

漢字編碼

漢字編碼 一、漢字所占的字節數 對于一個字符串sizeof("請放手")&#xff0c;結果值是4。測試操作系統&#xff1a;Centos 6.4&#xff0c;硬件平臺&#xff1a;Windows 7 32位 VirtualBox 4.3.12。看來用sizeof()來計算漢字所占用的字節或空間是不準確的。strlen(&…

Noise噪音halcon算子,持續更新

目錄add_noise_distributionadd_noise_whitegauss_distributionnoise_distribution_meansp_distributionadd_noise_distribution 功能&#xff1a;向一個圖像添加噪聲。 add_noise_white 功能&#xff1a;向一個圖像添加噪聲。 gauss_distribution 功能&#xff1a;產生一…

sublime text3 package control 報錯

安裝sublime text3之后&#xff0c;安裝package control 報錯&#xff0c;錯誤信息&#xff1a;There are no packages available for installation 根據提示&#xff0c;找到錯誤解決辦法&#xff1a;https://packagecontrol.io/doc... 其實意思就是你的電腦代理出了問題&…

HTML圖片元素(標記)

<html> <head> <title>第一個網頁</title> </head> <body> ***************圖片元素******************</br> <img srcmm.jpg /> </body> </html> 新建一個文件夾“text”,在text文件夾內新建index.html并放入一張…

Optical-Flow光流halcon算子,持續更新

目錄optical_flow_mgunwarp_image_vector_fieldvector_field_lengthderivate_vector_fieldoptical_flow_mg 功能&#xff1a;計算兩個圖像之間的光流。 unwarp_image_vector_field 功能&#xff1a;使用一個矢量場來展開一個圖像。 vector_field_length 功能&#xff1a;計…

Oracle中procedure和function創建舉例

Procedure創建與執行&#xff1a;Case1&#xff1a; create or replace procedure procedure_name(id user.table_name.columne_name%type)is begin delete from user.table_name where columne_nameid;exception when others then dbms_output.put_line(errors);end&#xff1…

Liunx 中tr的用法

1、將/etc/issue文件中的內容轉換為大寫后保存至/tmp/issue.out文件中cat /etc/issue |tr a-z A-Z > /tmp/issue.out2、將當前系統登錄用戶的信息轉換為大寫后保存至/tmp/who.out文件中who | tr a-z A-Z >> who.out3、一個linux用戶給root發郵件&#xff0c;要who求郵…

ASP.NET Aries 3.0發布(附帶通用API設計及基本教程介紹)

主要更新&#xff1a; 1&#xff1a;升級處理機制&#xff08;js請求由同步變更為異步&#xff09; 2&#xff1a;優化前端JS&#xff1a;包括API和配置方式。 3&#xff1a;增加InputDialog功能。 4&#xff1a;增遠遠程驗證功能。 5&#xff1a;優化權限安全機制。 6&#xf…

多線程并發之原子性(六)

最近在網上找到好多的多線程關于原子性的例子&#xff0c;說的都不是非常的明確&#xff0c;對于剛學習多線程的新手而言很容誤導學員&#xff0c;在這里&#xff0c;我通過多個例子對多線程的原子性加以說明。 例子一&#xff1a;傳統技術自增 package face.thread.volatilep;…

Points角點halcon算子,持續更新

目錄corner_responsedots_imagepoints_foerstnerpoints_harrispoints_harris_binomialpoints_lepetitpoints_sojkacorner_response 功能&#xff1a;在圖像中尋找角點。 dots_image 功能&#xff1a;在一個圖像中增強圓形點。 points_foerstner 功能&#xff1a;使用Frstn…

預編譯頭文件來自編譯器的早期版本,或者預編譯頭為 C++ 而在 C 中使用它(或相反)

當 Visual C 項目啟用了預編譯頭 (Precompiled header) 功能時&#xff0c;如果項目中同時混合有 .c 和 .cpp 源文件&#xff0c;則可能收到 C1853 編譯器錯誤&#xff1a;fatal error C1853: pjtname.pch precompiled header file is from a previous version of the compiler…

甲骨文稱 Java 序列化的存在是個錯誤,計劃刪除

甲骨文計劃從 Java 中去除序列化功能&#xff0c;因其在安全方面一直是一個棘手的問題。 Java 序列化也稱為 Java 對象序列化&#xff0c;該功能用于將對象編碼為字節流...Oracle 的 Java 平臺小組的首席架構師 Mark Reinhold 說&#xff1a;“刪除序列化是一個長期目標&#x…

CreateProcess

Windows 進程創建完整過程&#xff08;除去細節&#xff09; 當前流程是分析WinXP x86得到的&#xff0c;在最新版本Windows上不一定正確&#xff0c;但是可以做一個參考&#xff0c; 由于我這里符號并不全&#xff0c;所以導致我這里有些東西看到的可能是錯誤的&#xff0c;誤…

系統:Centos 7.2 內核3.10.0-327.el7.x86_64 # 內核需要高于2.6.32

系統&#xff1a;Centos 7.2 內核3.10.0-327.el7.x86_64 # 內核需要高于2.6.32 Drbd : 192.168.8.111&#xff1a;node1/dev/drdb0 /mydeta 192.168.8.112 : node2Mysql_vip: 192.168.8.200 #下章實現 # 需要的軟件包&#xff1a;mariadb-5.5.53-linux-i686.tar.gzdrbd84-utils…

Smoothing濾波處理halcon算子,持續更新

目錄anisotropic_diffusionbilateral_filterbinomial_filtereliminate_min_maxeliminate_spfill_interlacegauss_filterguided_filterinfo_smoothisotropic_diffusionmean_imagemean_nmean_spmedian_imagemedian_rectmedian_separate_median_weightedmidrange_imagerank_imager…

日志文件在VS中輸出為亂碼問題

原因&#xff1a;主要是文件文字格式問題&#xff08;使用使用 Unicode 字符集&#xff09;&#xff1a;修改項目/屬性/常規/字符集/ 未設置