iOS app效能優化的那些事 二

2021-07-22 16:59:10 字數 3684 閱讀 2979

tableview 滑動不流暢

那碰到這種情況該怎麼處理,分析影象動畫效能主要用的是core animation這個元件,先簡單介紹一下裡面一些經常用到的選項:

當你碰到效能問題的時候,你可以思考一下:

是否受到cpu或者gpu的限制?

是否有不必要的cpu渲染?

是否有太多的離屏渲染操作?

是否有太多的圖層混合操作?

是否有奇怪的格式或者尺寸?

是否涉及到昂貴的view或者效果?

view的層次結構是否合理?

那麼哪些是你最該開始考慮的方向呢?通常發生圖形效能問題的時候,比如列表滑動不順暢、動畫卡頓等,大部分都是由於offscreen rendering(離屏渲染)或者blending導致的,因為這在動畫的每一幀都會涉及到。

什麼是offscreen-render?offscreen-render涉及的內容比較多,有offscreen-render那就有onscreen render,onscreen render指的是gpu在當前用於顯示的螢幕緩衝區進行渲染,相反offscreen-render就是不在當前的螢幕快取區,而在另外的緩衝區進行渲染,offscreen-render有兩種形式:

cpu的offscreen-render

使用cpu來完成渲染操縱,通常在你使用:

gpu的offscreen-render

使用gpu在當前螢幕緩衝區以外開闢乙個新的緩衝區進行繪製,通常發生的情況有:

渲染流程

offscreen-render對效能到底有什麼影響?通常大家說的離屏渲染指的是gpu這塊(當然cpu這塊也會有影響,也需要消耗一定的資源),比如修改了layer的陰影或者圓角,gpu需要做額外的渲染操作。通常gpu在做渲染的時候是很快的,但是涉及到offscreen-render的時候情況就可能有些不同,因為需要額外開闢乙個新的緩衝區進行渲染,然後繪製到當前螢幕的過程需要做onscreen跟offscreen上下文之間的切換,這個過程的消耗會比較昂貴,涉及到opengl的pipeline跟barrier,而且offscreen-render在每一幀都會涉及到,因此處理不當肯定會對效能產生一定的影響,所以可以的話儘量減少offscreen-render的圖層,檢視哪些圖層需要離屏渲染可以用instruments的core animation工具進行檢測,color offscreen-rendered yellow選項會將對應的圖層標記為黃色。

假如最上層的view是不透明的,那直接使用這個view的對應顏色之就可以,但如果view是透明的,在計算畫素的顏色值時就需要計算它下面圖層,透明的檢視越多,計算量就越大,因此也會對圖形的效能產生一定的影響,所以可以的話也儘量減少透明圖層的數目。

下面給出乙個簡單demo的優化過程,這個demo裡面涉及到的問題是在實際專案中所碰到的,也就是最上面那張圖里列表滑動不流暢情況---由陰影以及圓角導致的offscreen-render。

整個頁面就是乙個簡單的tableview,其中頭像為圓角,乙個label有陰影效果,滑動的時候在ipod上幀率只有可憐的28fps。

其中黃色的區域就是離屏渲染的地方,也就是含有圓角跟陰影的layer。

shadowpath

設定label的陰影效果可以通過:

cell.sign.layer.shadowoffset = cgsizemake(0, 2);

cell.sign.layer.shadowopacity = 0.5;

cell.sign.layer.shadowcolor = [uicolor blackcolor].cgcolor;

但是你可以發現這會導致離屏渲染,乙個簡單的不需要離屏渲染的方法就是制定陰影的路徑,也就是設定layer的shadowpath屬性,通過instruments發現陰影的地方沒有黃色了,幀率也提高到了40fps:

設定shadowpath消除離屏渲染.png

rasterize

對於圓角這種類似導致的效能問題,最簡單的就是在列表中不要使用圓角,假如要使用圓角的話,一種最快提公升效能的方式就是設定layer的shouldrasterize為yes:

cell.layer

.shouldrasterize = yes;

cell.layer

.rasterizationscale = [uiscreen mainscreen].scale;

雖然被rasterize的圖層也會引起離屏渲染,如下圖所示,整個cell都被標示為黃色:

layer設定shouldrasterize=yes之後,會把被光柵化的圖層儲存成位圖並快取起來,其中圓角或者陰影之類的效果也是直接儲存到位圖當中,當需要渲染到螢幕上的時候只需要到快取中去取對應的點陣圖進行顯示就行了,加快了整個渲染過程。可以通過勾選instruments core animation中的color hits green and misses red選項來檢視圖層是否被快取了,如果圖層顯示為綠色則表示已經被快取起來了,也就是這個緩衝區的內容被復用了,不用在去重新建立緩衝區,反之則是用紅色標示。如下圖可以看到設定shouldrasterize之後,cell都被標示為綠色了,如果滑動過程中發現都是紅色的證明就有問題了:

再看看現在滑動的幀率:

優化後.png

可以發現現在滾動的效能大大提高了,光柵化對於那些有很多子view巢狀在一起、view的層級複雜或者有很複雜特效效果的圖層有很明顯的提公升,因為這些內容都被快取到位圖當中了。但是使用光柵化需要注意一些內容:

圖形效能這塊有什麼好的想法也可提出來交流一下~~

參考:

app 效能優化的那些事

iphone上面的應用一直都是以流暢的操作體驗而著稱,但是由於之前開發人員把注意力更多的放在開發功能上面,比較少去考慮效能的問題,可能這其中涉及到objective c,c 跟lua,優化起來相對複雜一些,導致應用在比如touch等較低端的產品上,光從啟動到進入頁面就花了將近一分鐘的時間,頁面之間的...

iOSAPP效能優化

2 本地載入方式 本地載入常用方法有兩種 1 uiimage imagenamed 多次使用時使用,需要使用此方式加入快取 2 uiimage alloc initwithcontentsoffile 不常使用時,不使用快取 3 不要阻塞主線程 開發中除了ui處理外,其它任務盡量放在後台執行緒載入。...

iOS APP效能優化

這篇文章總結了開發中常用到的一些效能優化點 a.uiimage imagenamed xx.png 多次使用時使用,需要使用此方式加入快取 b.uiimage alloc initwithcontentsoffile xx.png 不常使用時,不使用快取 3 不要阻塞主線程開發中除了ui處理外,其它...