界面流暢度 大都跟list scrollView有緊密關聯
流暢的視覺:就是如絲般順滑
不流暢視覺:”卡頓”,”抖動”,”遲頓感”
以上兩種狀態的描述 都是基於主觀感覺,對於開發者來說 確實應該有一個臨界指標來參考,自己寫的東西是否還有優化的空間呢.
Frames per Second(每秒幀數) 這個指標 可以通過Instruments 工具中的 Core Animation來觀察.(xCode -> Tools -> Instrument)
幀數為 0 說明頁面處於靜止 只要頁面一動起來,這個幀數就會有變化 然后再趨於靜止.也就是說頁面 滾動起來幀數是一個呈”非對稱”拋物線的走勢.
所以達到峰值的幀數 會呈現連續變化的一個狀態 那么這個就是是它的流暢度 ,一般普通的一個list 滾動起來 流暢度 達到60左右 (親測自己的app的一個普通頁面),一個復雜頁面53 - 60(親測).網上有人這么說”45幀每秒,這個幀率已經讓人感覺到不那么順滑了,如果低於40幀每秒,普通用戶就會察覺明顯的不流暢了”.所以大家可以根據這些做參考,或者 是 測試自己的應用 比較幾個普通頁面 和一個復雜頁面也可以有一個相對的參照.就可從理論上分析 是否這個相對比較復雜的頁面是否值得優化呢.
可以優化的地方(就是平常拍腦門能想到的地方)
1.CPU:可以通過Instruments里面的工具檢測cpu等 查出 到底是實現的哪個功能比較增加CPU的負擔
2.如果是tableView. 組織數據很繁瑣沒有用model來映射? 是否cell重用? 繪制高度的方法是不是很冗長,不斷的在重復計算? 需要刷新tableView 使用了不恰當地方式?
3.在滾動視圖中 圓角的處理
一般情況下我們會這樣做:
.layer.masksToBounds = YES;
.layer.cornerRadius = imageView.size.width * 0.5;
這個方法在滾動視圖中會是特別影響性能
原因:
導致拖慢幀率的原因其實都是Off-Screen Rendering(離屏渲染).
離屏渲染:是指CPU在當前屏幕緩沖區以外再開辟一個新的緩沖區進行渲染操作.
離屏渲染是一個很好優化性能的方式,但是頻繁發生離屏渲染(滾動屏幕 就會很頻繁啊)是非常耗時的。如果是一個圓角幾乎不會對幀率有太大影響,關鍵數量要是好多個.通過上面的定義可以看出”離屏渲染”關鍵不是渲染 而是 離屏.
離屏代價:主要是創建緩沖區和上下文切換的原因。創建新的緩沖區代價都不算大,付出最大代價的是上下文切換!!!!!(滿紙荒唐言 一把辛酸淚 誰被坑過 誰知道)
關於上下文切換:
上下文切換在哪都是一個相當耗費時間的操作,不論是 CPU渲染或是進程切換.其過程:
(1)我們要保證當前屏幕渲染環境
(2)切換到一個新的繪制環境—>申請繪制資源—>初始化環境—>開始繪制—>繪制結束—>銷毀繪制環境
(3)回到主屏幕呈現 或者 再開辟一個新的離屏渲染重復(2)
解決:
那么如何應對這個問題呢?不要在滾動視圖使用cornerRadiu 可以使用下面的方法
(1)非要作死使用layer.ornerRadius,記得還要添加下面方法
.layer.shouldRasterize = YES; //這樣大部分情況下可以馬上挽救你的幀數在55幀每秒以上。shouldRasterize = YES會使視圖渲染內容被緩存起來,下次繪制的時候可以直接顯示緩存,當然要在視圖內容不改變的情況下。(具體解釋 layer的頭文件,進入查看這個屬性的英文說明 不覺明厲)
.layer.rasterizationScale = [UIScreen mainScreen].scale;//需要適當設置"抗鋸齒" 否則在retina的設備上這些視圖會出現鋸齒狀。(具體了解參看 layer 屬性)
(2)如果可以用切圖遮罩代替的話 會效率很高
(3)預先緩存住 圓角的圖片(預處理圓角圖片在后台處理,處理完畢后緩存起來,再在主線程顯示),來避免了離屏渲染
參考資源
http://www.zhihu.com/question/20382396 (知乎)
http://www.cnblogs.com/ioriwellings/p/5011993.html (更具體的解決方案)