iOS開發(fā) 容易忽略的幀率殺手:陰影

原文鏈接

離屏渲染

關(guān)于 UITableView、UICollectionView 滑動卡頓仍源,大家都會想起一個大殺手:圓角童本。

說起圓角,其實是針對 UITableView几颜、UICollectionView 等列表視圖 Cell 及其子視圖中包含的需要重復(fù)大量切圓角的場景倍试,關(guān)于這個問題當(dāng)時在開發(fā)圈里也曾經(jīng)引起過熱議,解決方案也挺多蛋哭,這里就不再過多的去討論县习。

不過有一點值得注意的是,可能是蘋果也意識到離屏渲染會產(chǎn)生性能問題谆趾,所以 iOS9 及之后的 iOS 版本對 UIImageView 離屏渲染做了一些優(yōu)化躁愿。

iOS 版本上的優(yōu)化

  • iOS 9.0 之前 UIImageView 跟 UIButton 設(shè)置圓角都會觸發(fā)離屏渲染。

  • iOS 9.0 之后 UIButton 設(shè)置圓角會觸發(fā)離屏渲染沪蓬,而 UIImageView 里 png 圖片設(shè)置圓角不會觸發(fā)離屏渲染了彤钟,但是其他類型的圖片依然會觸發(fā)離屏渲染,而且如果設(shè)置其他陰影效果之類的也是會觸發(fā)離屏渲染的跷叉。

Instruments 監(jiān)測離屏渲染

Instruments 的 Core Animation 工具中有幾個和離屏渲染相關(guān)的檢查選項:

  • Color Offscreen-Rendered Yellow
    開啟后會把那些需要離屏渲染的圖層高亮成黃色逸雹,這就意味著黃色圖層可能存在性能問題营搅。
  • Color Hits Green and Misses Red
    如果 shouldRasterize 被設(shè)置成 YES,對應(yīng)的渲染結(jié)果會被緩存梆砸,如果圖層是綠色剧防,就表示這些緩存被復(fù)用;如果是紅色就表示緩存會被重復(fù)創(chuàng)建辫樱,這就表示該處存在性能問題了峭拘。

注意:Xcode9.3之后的版本功能上做的調(diào)整,這些選項已經(jīng)直接集成到 Xcode 里面了

xcode-offscreen-rendered.png

繪制陰影造成的性能問題

不過我們今天主角并不是圓角狮暑,不過殺傷力并不亞于圓角鸡挠,他的名字叫做陰影

其實這個東西平常都是設(shè)計同學(xué)或者產(chǎn)品同學(xué)搬男,為了增強(qiáng)頁面的視覺效果而添加的拣展。

一般的實現(xiàn)方式是這樣的:

// 這里我們只是給 cell 添加陰影效果,其他什么都不做缔逛,看看陰影對設(shè)備性能的影響
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell: UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: ViewController.cellId, for: indexPath)
    cell.backgroundColor = UIColor.gray
    cell.layer.shadowOffset = CGSize(width: 0, height: 2)
    cell.layer.shadowOpacity = 0.5

    return cell
}

打開 Xcode 中監(jiān)測離屏渲染的選項之后备埃,展示在界面上是這個效果(Cell全都觸發(fā)了離屏渲染):

[圖片上傳失敗...(image-31dd3-1552466180881)]

然后我們按 Command+I 快捷鍵進(jìn)入 Profile,選擇 CoreAnimation 檢測幀率及CPU褐奴、GPU利用率(本文所用的 iPhone 設(shè)備為 iPhone6s按脚,系統(tǒng)版本為 iOS12.0.1)。

開啟錄制之后敦冬,操作也很簡單辅搬,就只是簡單的上下滑動列表。

可以看到監(jiān)測到的數(shù)據(jù)如下:

[圖片上傳失敗...(image-317498-1552466180881)]

其實從手機(jī)端的體驗感覺還說的過去脖旱,幀率基本能達(dá)到50fps堪遂,卡頓感比較弱,大部分用戶還是可以接受的萌庆。但是這里比較致命的問題是:1. 我們的列表里還沒有填充數(shù)據(jù)溶褪,僅僅是加了個陰影而已啊,加入了業(yè)務(wù)邏輯后践险,幀率肯定會進(jìn)一步降低猿妈。2. GPU 使用率高的可怕,一般情況下捏境,移動設(shè)備上面幾個耗電大戶無非就是 CPU于游、GPU、WiFi 模塊垫言,GPU 占用率這么高贰剥,用戶最直觀的感受就是:我的手機(jī)是不是該換電池了?筷频?蚌成?這對于一個高使用率的 App 來說簡直是不能接受的前痘。

發(fā)現(xiàn)問題之后,其實解決方案也很簡單:將 Cell 的 layer 進(jìn)行光柵化担忧。雖然光柵化也會觸發(fā)離屏渲染芹缔,但是光柵化會將陰影合成到圖片中,cell 重用的時候直接加載圖片即可瓶盛,不必每次都繪制陰影最欠,從而相對的提升性能。

cell.layer.shouldRasterize = true

不過單獨設(shè)置這個屬性是不夠的惩猫,因為默認(rèn)情況下芝硬,光柵化生成的圖片是 @1x 的,而現(xiàn)在 iOS 設(shè)備顯示器基本都是 @2x 或者 @3x轧房,這樣就會造成顯示模糊拌阴,鋸齒感強(qiáng)烈,影響視覺效果奶镶。

layer 有一個屬性就是專門解決這個問題的:

/* The scale at which the layer will be rasterized (when the
 * shouldRasterize property has been set to YES) relative to the
 * coordinate space of the layer. Defaults to one. Animatable. */

open var rasterizationScale: CGFloat

那么要解決這個問題迟赃,只需要設(shè)置光柵化的默認(rèn)縮放系數(shù)為屏幕顯示倍率即可:

cell.layer.rasterizationScale = UIScreen.main.scale

更改完之后,我們打開 Xcode 中監(jiān)測離屏渲染的選項厂镇,把項目運行到設(shè)備上查看效果纤壁,這次已經(jīng)沒有明顯的離屏渲染了(光柵化觸發(fā)離屏渲染的過程很短,估計沒有捕捉到):

iOS-shadow.png

之后我們再次進(jìn)入 Profile剪撬,查看更改完之后的效果:

iOS-shadow-optimize.png

界面上顯示效果和修改之前一樣摄乒,滑動幀率有所提升,重要的是 GPU 利用率大大降低了残黑,用戶最直觀的體驗就是設(shè)備續(xù)航體驗更加友好了,再也不會被用4000ma·h大電池手機(jī)的朋友嘲笑電池一天幾沖了 [捂臉]斋否。

至此梨水,UICollectionViewCell 陰影效果造成列表滑動卡頓的問題就得以解決了,方案雖然很簡單茵臭,還是需要我們在日常開發(fā)中多注意這類容易引發(fā)性能問題的點疫诽,發(fā)現(xiàn)問題之后能夠及時的優(yōu)化。做好用戶體驗旦委,才能開發(fā)出更加優(yōu)秀 的 App奇徒!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市缨硝,隨后出現(xiàn)的幾起案子摩钙,更是在濱河造成了極大的恐慌,老刑警劉巖查辩,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胖笛,死亡現(xiàn)場離奇詭異网持,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)长踊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門功舀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人身弊,你說我怎么就攤上這事辟汰。” “怎么了阱佛?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵帖汞,是天一觀的道長。 經(jīng)常有香客問我瘫絮,道長涨冀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任麦萤,我火速辦了婚禮鹿鳖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘壮莹。我一直安慰自己翅帜,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布命满。 她就那樣靜靜地躺著涝滴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胶台。 梳的紋絲不亂的頭發(fā)上歼疮,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機(jī)與錄音诈唬,去河邊找鬼韩脏。 笑死,一個胖子當(dāng)著我的面吹牛铸磅,可吹牛的內(nèi)容都是我干的赡矢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼阅仔,長吁一口氣:“原來是場噩夢啊……” “哼吹散!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起八酒,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤空民,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丘跌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袭景,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡唁桩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了耸棒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荒澡。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖与殃,靈堂內(nèi)的尸體忽然破棺而出单山,到底是詐尸還是另有隱情,我是刑警寧澤幅疼,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布米奸,位于F島的核電站,受9級特大地震影響爽篷,放射性物質(zhì)發(fā)生泄漏悴晰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一逐工、第九天 我趴在偏房一處隱蔽的房頂上張望铡溪。 院中可真熱鬧,春花似錦泪喊、人聲如沸棕硫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哈扮。三九已至,卻和暖如春蚓再,著一層夾襖步出監(jiān)牢的瞬間滑肉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工摘仅, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留赦邻,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓实檀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親按声。 傳聞我的和親對象是個殘疾皇子膳犹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355