iOS面試題整理---性能優化

[轉載]iOS性能優化

性能優化

在性能優化中一個最具參考價值的屬性是FPS:Frames Per Second,其實就是屏幕刷新率,蘋果的iphone推薦的刷新率是60Hz,也就是說GPU每秒鐘刷新屏幕60次,這每刷新一次就是一幀frame,FPS也就是每秒鐘刷新多少幀畫面。靜止不變的頁面FPS值是0,這個值是沒有參考意義的,只有當頁面在執行動畫或者滑動的時候,FPS值才具備參考價值,FPS值的大小體現了頁面的流暢程度高低,當低於45的時候卡頓會比較明顯。iphone

圖層混合:性能

每個layer是一個紋理,全部的紋理都以某種方式堆疊在彼此的頂部。對於屏幕上的每個像素,GPU須要算出怎麼混合這些紋理來獲得像素RGB的值。
測試

當Sa = 0.5時,RGB值爲(0.5, 0, 0),能夠看出,當兩個不是徹底不透明的CALayer覆蓋在一塊兒時,GPU大量作這種複合操做,隨着這中操做的越多,GPU越忙碌,性能確定會受到影響。優化

公式:動畫

R = S + D * ( 1 – Sa )spa

結果的顏色是源色彩(頂端紋理)+目標顏色(低一層的紋理)*(1-源顏色的透明度)。debug

當Sa = 1時,R = S,GPU將不會作任何合成,而是簡單從這個層拷貝,不須要考慮它下方的任何東西(由於都被它遮擋住了),這節省了GPU至關大的工做量。3d

怎麼檢測圖層混合:

一、模擬器debug- 選中 color blended layers紅色區域表示圖層發生了混合orm

二、Instrument-選中Core Animation-勾選Color Blended Layers

避免圖層混合:

一、確保控件的opaque屬性設置爲true,確保backgroundColor和父視圖顏色一致且不透明

二、如無特殊須要,不要設置低於1的alpha值

三、確保UIImage沒有alpha通道

UILabel圖層混合解決方法:

iOS8之後設置背景色爲非透明色而且設置label.layer.masksToBounds=YES讓label只會渲染她的實際size區域,就能解決UILabel的圖層混合問題

iOS8 以前只要設置背景色爲非透明的就行

爲何設置了背景色可是在iOS8上仍然出現了圖層混合呢?

UILabel在iOS8先後的變化,在iOS8之前,UILabel使用的是CALayer做爲底圖層,而在iOS8開始,UILabel的底圖層變成了_UILabelLayer,繪製文本也有所改變。在背景色的四周多了一圈透明的邊,而這一圈透明的邊明顯超出了圖層的矩形區域,設置圖層的masksToBounds爲YES時,圖層將會沿着Bounds進行裁剪 圖層混合問題解決了

iOS離屏渲染

怎麼檢測離屏渲染:

一、模擬器debug-選中color Offscreen - Renderd離屏渲染的圖層高亮成黃 可能存在性能問題

二、真機Instrument-選中Core Animation-勾選Color Offscreen-Rendered Yellow

離屏渲染的觸發方式

設置瞭如下屬性時,都會觸發離屏繪製:

一、layer.shouldRasterize(光柵化)

光柵化概念:將圖轉化爲一個個柵格組成的圖象。

光柵化特色:每一個元素對應幀緩衝區中的一像素。

二、masks(遮罩)

三、shadows(陰影)

四、edge antialiasing(抗鋸齒)

五、group opacity(不透明)

六、複雜形狀設置圓角等

七、漸變

八、drawRect

例如咱們日程常常打交道的TableViewCell,由於TableViewCell的重繪是很頻繁的(由於Cell的複用),若是Cell的內容不斷變化,則Cell須要不斷重繪,若是此時設置了cell.layer可光柵化。則會形成大量的離屏渲染,下降圖形性能。

若是將不在GPU的當前屏幕緩衝區中進行的渲染都稱爲離屏渲染,那麼就還有另外一種特殊的「離屏渲染」方式:CPU渲染。若是咱們重寫了drawRect方法,而且使用任何Core Graphics的技術進行了繪製操做,就涉及到了CPU渲染。整個渲染過程由CPU在App內同步地完成,渲染獲得的bitmap最後再交由GPU用於顯示。

如今擺在咱們面前得有三個選擇:當前屏幕渲染、離屏渲染、CPU渲染,該用哪一個呢?這須要根據具體的使用場景來決定。

儘可能使用當前屏幕渲染

鑑於離屏渲染、CPU渲染可能帶來的性能問題,通常狀況下,咱們要儘可能使用當前屏幕渲染。

離屏渲染 VS CPU渲染

因爲GPU的浮點運算能力比CPU強,CPU渲染的效率可能不如離屏渲染;但若是僅僅是實現一個簡單的效果,直接使用CPU渲染的效率又可能比離屏渲染好,畢竟離屏渲染要涉及到緩衝區建立和上下文切換等耗時操做

UIButton 的 masksToBounds = YES又設置setImage、setBackgroundImage、[button setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"btn_selected"]]];

下發生離屏渲染,可是[button setBackgroundColor:[UIColor redColor]];是不會出現離屏渲染的

關於 UIImageView,如今測試發現(現版本: iOS10),在性能的範圍以內,給UIImageView設置圓角是不會觸發離屏渲染的,可是同時給UIImageView設置背景色則確定會觸發.觸發離屏渲染跟 png.jpg格式並沒有關聯

平常咱們使用layer的兩個屬性,實現圓角

imageView.layer.cornerRaidus = CGFloat(10);

imageView.layer.masksToBounds = YES;

這樣處理的渲染機制是GPU在當前屏幕緩衝區外新開闢一個渲染緩衝區進行工做,也就是離屏渲染,這會給咱們帶來額外的性能損耗。若是這樣的圓角操做達到必定數量,會觸發緩衝區的頻繁合併和上下文的的頻繁切換,性能的代價會宏觀地表如今用戶體驗上——掉幀

光柵化

光柵化是將幾何數據通過一系列變換後最終轉換爲像素,從而呈如今顯示設備上的過程,光柵化的本質是座標變換、幾何離散化

咱們使用 UITableView 和 UICollectionView 時常常會遇到各個 Cell 的樣式是同樣的,這時候咱們可使用這個屬性提升性能:

cell.layer.shouldRasterize=YES;

cell.layer.rasterizationScale=[[UIScreenmainScreen]scale];

頁面間跳轉的性能優化:



T

相關文章
相關標籤/搜索