iOS性能優(yōu)化 視圖渲染

iOS性能優(yōu)化的一個(gè)重要方面是視圖渲染撵术,在渲染的過(guò)程中避免出現(xiàn)圖層混合钠乏,離屏渲染等問(wèn)題,從而減少CPU和GPU的性能開(kāi)銷(xiāo)墩划,達(dá)到性能優(yōu)化的目的涕刚。

我們?cè)陂_(kāi)發(fā)調(diào)試過(guò)程中,可通過(guò)Xcode中的視圖調(diào)試選項(xiàng)來(lái)幫助我們快速查找出渲染過(guò)程中的問(wèn)題乙帮。
真機(jī)調(diào)試運(yùn)行App項(xiàng)目杜漠,在Xcode的工具欄中選擇,Debug -> View Debugging -> Rendering察净,其中有9個(gè)選項(xiàng)驾茴。

Xcode視圖調(diào)試選項(xiàng)路徑.png

若使用的是模擬器,在Simulator工具欄的Debug選欄中也有視圖調(diào)試的選項(xiàng)氢卡。

Simulator視圖調(diào)試選項(xiàng)路徑.png
選項(xiàng) 說(shuō)明
Color Blended Layers 圖層混合沟涨,產(chǎn)生了圖層混合視圖上會(huì)標(biāo)注為紅色,沒(méi)有發(fā)生圖層混合視圖上會(huì)標(biāo)注為綠色异吻。紅色越多,性能越差。
Color Hit Green and Misses Red 光柵化诀浪,光柵化會(huì)將layer預(yù)先渲染成位圖bitmap棋返,然后被緩存,緩存未被復(fù)用則標(biāo)注為紅色雷猪,緩存被復(fù)用會(huì)標(biāo)注為綠色睛竣。紅色越多,性能越差求摇。
Color Copied Images GPU 不支持的顏色格式的圖片需要被復(fù)制到CPU進(jìn)行顏色格式轉(zhuǎn)換射沟,因此這樣的圖片會(huì)被標(biāo)注為藍(lán)色。藍(lán)色越多与境,性能越差验夯。
Color Layer Formats 圖層顏色格式, 暫不清楚摔刁。
Color Immediately 立即刷新挥转, 通常以每10毫秒一次的頻率更新圖層調(diào)試顏色。選中這個(gè)選項(xiàng)則設(shè)置每幀畫(huà)面都會(huì)刷新共屈,在需要加快顏色刷新頻率的場(chǎng)景下使用绑谣,通常情況下用不到。
Color Misaligned Images 圖片錯(cuò)位拗引,這個(gè)選項(xiàng)檢查圖片是否被縮放借宵,以及像素是否對(duì)齊。被縮放的圖片會(huì)被標(biāo)記為黃色矾削,像素不對(duì)齊則會(huì)標(biāo)注為紫色壤玫。黃色、紫色越多怔软,性能越差垦细。
Color Offscreen-Rendered Yellow 離屏渲染,產(chǎn)生離屏渲染的圖層會(huì)標(biāo)注為黃色挡逼。黃色越多括改,性能越差。
Color Compositing Fast-Path Blue 快速路徑家坎,使用 OpenGL 繪制的圖層會(huì)標(biāo)注為藍(lán)色嘱能。藍(lán)色越多,性能越好虱疏。
Flash Updated Regions 重繪區(qū)域惹骂,進(jìn)行了重繪的區(qū)域會(huì)標(biāo)注成黃色,使用Core Graphics重新繪制會(huì)消耗性能做瞪,重繪區(qū)域越小越少对粪,性能越好右冻。

調(diào)試這幾個(gè)選項(xiàng),我們來(lái)具體看看著拭,針對(duì)視圖渲染有哪些具體問(wèn)題需要優(yōu)化纱扭。

Color Hit Green and Misses Red(圖層混合)

在多個(gè)UI視圖疊加的情況下,如果有透明或者半透明的控件儡遮,那么GPU會(huì)根據(jù)透明度去計(jì)算這些layer疊加在一起最終的顯示的顏色乳蛾。舉例,如果頂層VeiwA顏色是紅色RGB(255,0,0)鄙币,透明度是40%肃叶,底層ViewB顏色是綠色RGB(0,255,0),那么最終疊加顯示出來(lái)顏色是RGB(102,153,0)十嘿。
計(jì)算公式

RGB(混合) = RGB(A) * alpha + RGB(B) * (1-alpha)

這個(gè)渲染過(guò)程會(huì)消耗GPU性能因惭,因此要避免出現(xiàn)圖層混合。

  • 方法:去除透明度详幽,給View添加alpha為1的背景色筛欢,這樣在視圖疊加時(shí),因?yàn)闆](méi)有了透明度唇聘,重疊部分直接按照頂層視圖的顏色去顯示版姑。
    若視圖是UIImageView,不僅需要自身這個(gè)容器的alpha為1迟郎,并且imageView包含的內(nèi)容圖片也是不透明的剥险。

順便提一下:UIView的opaque屬性默認(rèn)為Yes。
opaque這個(gè)屬性不是決定視圖是否透明宪肖,而是決定在視圖渲染過(guò)程的處理方式表制。視圖是否透明跟 alpha 和 hidden 有直接關(guān)系。
如果視圖不透明控乾,就設(shè)置opaque為Yes么介,表示圖形系統(tǒng)會(huì)將視圖視為完全不透明,完全不透明視圖應(yīng)該使用完全不透明的內(nèi)容來(lái)填充蜕衡,該內(nèi)容的alpha值應(yīng)該為1.0(自身的alpha和填充顏色的alpha都應(yīng)該為1.0)壤短,這樣圖形系統(tǒng)將不考慮它與其他視圖的混合顏色計(jì)算,從而提高性能慨仿。若設(shè)置為NO久脯,圖形系統(tǒng)通常會(huì)將視圖與其他內(nèi)容合成,消耗性能镰吆。如果View是在scrollView中或者在動(dòng)畫(huà)中帘撰,對(duì)性能的提升更為明顯。
有些View的子類(lèi)使用drawRect:方法繪制自己的內(nèi)容万皿,那么opaque屬性對(duì)其無(wú)效摧找。

Color Hit Green and Misses Red(光柵化)

這個(gè)選項(xiàng)用來(lái)檢測(cè)是否正確使用layer的shouldRasterize屬性核行,該屬性默認(rèn)是NO,若 shouldRasterize為YES則開(kāi)啟光柵化蹬耘。光柵化是將layer預(yù)先渲染成位圖(bitmap)钮科,然后緩存起來(lái),緩存未被復(fù)用則標(biāo)注為紅色婆赠,緩存被復(fù)用會(huì)標(biāo)注為綠色,紅色越多佳励,性能越差休里。使用光柵化的視圖清晰度會(huì)降低。

  • 對(duì)于不是頻繁繪制的靜態(tài)視圖赃承,若需要添加陰影妙黍、圓角等,進(jìn)行光柵化處理瞧剖,會(huì)對(duì)性能有提升拭嫁。
  • 對(duì)于會(huì)頻繁繪制的視圖,如tableViewCell抓于,一般不要使用光柵化做粤,開(kāi)啟光柵化就會(huì)產(chǎn)生離屏渲染,因?yàn)楣鈻呕木彺婢褪钱?dāng)前屏幕緩沖區(qū)以外新開(kāi)辟緩沖區(qū)捉撮。由于tableViewCell的繪制非常頻繁怕品,內(nèi)容在不斷的變化,會(huì)不斷的產(chǎn)生緩存巾遭,造成大量的離屏渲染降低性能肉康。緩存的保留時(shí)間為100ms,如果在100ms內(nèi)沒(méi)有使用緩存的對(duì)象灼舍,則會(huì)將緩存釋放吼和。正因如此,會(huì)出現(xiàn)下面的現(xiàn)象骑素。 若在tableViewCell中開(kāi)啟光柵化炫乓,剛進(jìn)入頁(yè)面時(shí), 所有使用了光柵化的視圖layer都標(biāo)注為紅色砂豌,因?yàn)殡m進(jìn)行了光柵化緩存厢岂,但是沒(méi)有被復(fù)用;在滑動(dòng)tableView時(shí)阳距,若滑動(dòng)幅度比較小塔粒,沒(méi)有新的視圖出現(xiàn),那么光柵化緩存被復(fù)用筐摘,所有視圖的layer都標(biāo)注為綠色卒茬。隨著滑動(dòng)幅度變大船老,新的視圖出現(xiàn),新視圖的光柵化緩存被創(chuàng)建圃酵,但是沒(méi)有被復(fù)用柳畔,就會(huì)被標(biāo)注為紅色,但是光柵化緩存的保留時(shí)間為100ms郭赐,新視圖標(biāo)注的紅色就會(huì)變?yōu)榫G色薪韩。
    光柵化的使用有利有弊,正確的使用光柵化可以得到一定程度的性能提升捌锭。

Color Copied Images (圖片被復(fù)制)

蘋(píng)果的GPU只解析32bit的顏色格式俘陷,32bit的顏色格式由RGBA(紅、綠观谦、藍(lán)拉盾、透明度)四個(gè)顏色通道組成,每一個(gè)顏色通道都占據(jù)8bit豁状,取值范圍是[0, 255]捉偏。
如果某圖片是GPU 不支持的顏色格式,那么圖片需要被復(fù)制到CPU進(jìn)行顏色格式轉(zhuǎn)換泻红,這樣的圖片會(huì)被標(biāo)注為藍(lán)色夭禽。藍(lán)色越多,性能越差承桥。

Color Layer Formats(圖層顏色格式)

這個(gè)選項(xiàng)用來(lái)解析圖層的顏色格式驻粟,具體用途暫不清楚。
打開(kāi)這個(gè)選項(xiàng)后凶异,UILabel都會(huì)被標(biāo)注蜀撑,標(biāo)注為銀白色或橙色,UIImageView的圖片內(nèi)容有部分透明時(shí)標(biāo)注為紫羅蘭色剩彬,全不透明時(shí)標(biāo)注為橙色酷麦;有趣的是,xib中調(diào)整UILabel的textColor喉恋,當(dāng)RGB三個(gè)顏色通道的色值一致時(shí)(如000000沃饶、999999、FFFFFF等)轻黑,UILabel會(huì)被標(biāo)注為銀白色糊肤,當(dāng)RGB三個(gè)顏色通道的色值不一樣時(shí)(如999897等),UILabel會(huì)被標(biāo)注為橙色氓鄙。

Color Immediately(顏色刷新)

這個(gè)選項(xiàng)用來(lái)調(diào)整顏色刷新頻率馆揉。通常情況是以每10毫秒一次的頻率更新圖層調(diào)試顏色,選中這個(gè)選項(xiàng)則設(shè)置每幀畫(huà)面都會(huì)刷新抖拦,沒(méi)有了10毫秒的延遲升酣。在需要加快顏色刷新頻率的場(chǎng)景下使用舷暮,通常情況下用不到。

Color Misaligned Images(圖片錯(cuò)位)

這個(gè)選項(xiàng)用來(lái)檢測(cè)圖片在展示時(shí)是否被放大或縮小噩茄,以及像素是否對(duì)齊下面。如果image.size和imageView.size不匹配(例如,image的實(shí)際大小是50×50绩聘,imageView的尺寸大小25×25沥割,或者為200×200),圖片在展示時(shí)會(huì)縮放或者放大圖片凿菩,會(huì)消耗資源蓄髓,imageView會(huì)被標(biāo)注為黃色,黃色越多,性能越差预茄。避免出現(xiàn)黃色標(biāo)注刨沦,將imageView.size設(shè)置成與image.size一樣的想诅。

Color Offscreen-Rendered Yellow(離屏渲染)

這個(gè)選項(xiàng)用來(lái)檢測(cè)是會(huì)把那些離屏渲染的圖層顯示為黃色篮灼。黃色越多,性能越差旦袋。

屏幕渲染有 當(dāng)前屏幕渲染 和 離屏渲染 兩種方式。

  • 當(dāng)前屏幕渲染(On-Screen Rendering):GPU的渲染操作是在當(dāng)前用于顯示的屏幕緩沖區(qū)中進(jìn)行。
  • 離屏渲染(Off-Screen Rendering):GPU在當(dāng)前屏幕緩沖區(qū)以外新開(kāi)辟一個(gè)緩沖區(qū)進(jìn)行渲染操作专控。離屏渲染會(huì)先在屏幕外創(chuàng)建新緩沖區(qū)失都,離屏渲染結(jié)束后咳焚,再?gòu)碾x屏切到當(dāng)前屏幕, 把離屏的渲染結(jié)果顯示到當(dāng)前屏幕上,這個(gè)上下文切換的過(guò)程很消耗性能,開(kāi)發(fā)中應(yīng)盡可能避免離屏渲染。

常見(jiàn)的會(huì)引起離屏渲染的操作:

  • shadows(陰影):在設(shè)置陰影屬性時(shí)典勇,一定要指定陰影路徑,可以避免離屏渲染般码。
view.layer.shadowOffset = CGSizeMake(0, 2);
view.layer.shadowOpacity = 1;
view.layer.shadowRadius = 4;
view.layer.shadowPath = CGPathCreateWithRect(view.bounds, nil);
//或者
view.layer.shadowPath =UIBezierPath(view.bounds).CGPath走净;
  • shouldRasterize(光柵化):上面有提到過(guò),開(kāi)啟光柵化就會(huì)產(chǎn)生離屏渲染,因?yàn)楣鈻呕木彺婢褪钱?dāng)前屏幕緩沖區(qū)以外新開(kāi)辟緩沖區(qū)。雖然會(huì)產(chǎn)生離屏渲染慕淡,但是不代表就一定會(huì)降低性能。若頁(yè)面初始創(chuàng)建視圖時(shí),很多視圖需要設(shè)置圓角,陰影拂檩,遮罩等屬性,一下子處理這些需要圖層混合的渲染嘲碧,很消耗性能稻励,但是開(kāi)啟光柵化,相同的效果只被渲染了一次愈涩,然后一直在緩存中被復(fù)用望抽,減少了整個(gè)渲染的頻度和時(shí)間加矛,從而提升性能∶焊荩總之斟览,視情況而定,采用最優(yōu)的方式來(lái)優(yōu)化性能舰蟆。

  • masks(遮罩):?jiǎn)为?dú)設(shè)置layer.cornerRadius趣惠,或者設(shè)置layer.masksToBounds為Yes,并不會(huì)引起離屏渲染身害,但是同時(shí)設(shè)置這兩個(gè)屬性會(huì)引起離屏渲染味悄。
    設(shè)置圓角:
    1.使用帶圓角的圖片,這樣最直接塌鸯。
    2.iOS11之后侍瑟,通常設(shè)置layer.maskedCorners和layer.cornerRadius,再加上背景色可以了丙猬,在設(shè)置背景色時(shí)涨颜,UILabel或者UITextView不要設(shè)置backgroundColor,而是設(shè)置layer.backgroundColor茧球。

    label.layer.cornerRadius = 10;
    label.layer.backgroundColor = [UIColor redColor].CGColor;
    

    3.通過(guò)CAShapeLayer庭瑰,將繪制有圓角的layer賦值給layer.mask。該方法會(huì)引起離屏渲染抢埋。
    4.通過(guò)混合圖層的方式弹灭,在需要添加圓角的視圖上再疊加一個(gè)部分透明的視圖,只對(duì)圓角部分進(jìn)行遮擋揪垄,疊加后達(dá)到有圓角的效果穷吮。多一個(gè)圖層會(huì)增加的工作量與離屏渲染相比微不足道。

Color Compositing Fast-Path Blue(快速路徑)

這個(gè)選項(xiàng)用來(lái)檢測(cè)是否是直接使用 OpenGL 繪制的饥努, 使用 OpenGL 繪制的圖層會(huì)標(biāo)注為藍(lán)色捡鱼。藍(lán)色越多,性能越好酷愧。如果僅僅使用 UIKitAPI驾诈,那么不會(huì)有任何效果。

Flash Updated Regions(重繪區(qū)域)

這個(gè)選項(xiàng)用來(lái)檢測(cè)是否出現(xiàn)重新繪制溶浴,進(jìn)行了重繪的區(qū)域會(huì)標(biāo)注成黃色翘鸭,使用Core Graphics重新繪制會(huì)消耗性能,因此重繪區(qū)域越小越少戳葵,性能越好就乓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子生蚁,更是在濱河造成了極大的恐慌噩翠,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件邦投,死亡現(xiàn)場(chǎng)離奇詭異伤锚,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)志衣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)屯援,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人念脯,你說(shuō)我怎么就攤上這事狞洋。” “怎么了绿店?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵吉懊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我假勿,道長(zhǎng)借嗽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任转培,我火速辦了婚禮恶导,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浸须。我一直安慰自己惨寿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布羽戒。 她就那樣靜靜地躺著,像睡著了一般虎韵。 火紅的嫁衣襯著肌膚如雪易稠。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天包蓝,我揣著相機(jī)與錄音驶社,去河邊找鬼。 笑死测萎,一個(gè)胖子當(dāng)著我的面吹牛亡电,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硅瞧,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼份乒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起或辖,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瘾英,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后颂暇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體缺谴,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年耳鸯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了湿蛔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡县爬,死狀恐怖阳啥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捌省,我是刑警寧澤苫纤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站纲缓,受9級(jí)特大地震影響卷拘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜祝高,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一栗弟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧工闺,春花似錦乍赫、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至叠殷,卻和暖如春改鲫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背林束。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工像棘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人壶冒。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓缕题,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親胖腾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子烟零,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容