iOS 性能優(yōu)化_微博優(yōu)化技巧

最近研究了一下微博,發(fā)現(xiàn)微博列表中可以優(yōu)化的點(diǎn)相當(dāng)多,先將比較容易優(yōu)化的點(diǎn)羅列如下:

  1. 預(yù)排版
    當(dāng)獲取到 API JSON 數(shù)據(jù)后,將每條 cell 需要的數(shù)據(jù)都在后臺線程計(jì)算并封裝成一個布局對象 cellLayout肪凛。cellLayout 包含有所有文本的 CoreText 排版結(jié)果、cell 內(nèi)部每個控件的高度辽社、cell 整體的高度伟墙。每個 cellLayout 占用的內(nèi)存并不多,所以當(dāng)生成后滴铅,可以全部緩存到內(nèi)存戳葵,以供稍后使用。這樣汉匙,tableView 在計(jì)算各個 cell 高度時拱烁,將不會消耗任何多余的計(jì)算量;當(dāng)把 CellLayout 設(shè)置到 cell 內(nèi)部時噩翠,cell 內(nèi)部也就不用再計(jì)算布局了戏自。
    對于通常的 tableView 來說,提前在后臺計(jì)算好布局結(jié)果是一個非常重要的性能優(yōu)化點(diǎn)伤锚。為了達(dá)到最高性能擅笔,可能會犧牲一些開發(fā)速度,不要使用 AutoLayout 等技術(shù)屯援,少用 UILabel 等文本控件猛们。如果你對性能的要求并不那么高,可以嘗試使用 TableView 的預(yù)估行高功能狞洋,并把每個 cell 高度緩存下來弯淘。這里有個百度知道團(tuán)隊(duì)的開源項(xiàng)目可以很方便的幫你實(shí)現(xiàn)這一點(diǎn):FDTemplateLayoutCell.

  2. 預(yù)渲染
    微博的頭像在某次改版中換成了圓形,當(dāng)頭像下載下來后徘铝,在后臺線程將頭像預(yù)先渲染為圓形并單獨(dú)保存到一個圖片緩存隊(duì)列中去耳胎。
    對于 tableView 來說,cell 內(nèi)容的離屏渲染會帶來較大的 GPU 消耗惕它。使用 layer 的圓角屬性在低性能的設(shè)備上快速滑動的時候怕午,盡管沒有感覺到較大的卡頓,但整體的平均幀數(shù)降了下來淹魄。用 Instument 查看的時候可以看到 GPU 已經(jīng)滿負(fù)荷運(yùn)轉(zhuǎn)郁惜,而 CPU 卻比較清閑。為了避免離屏渲染,應(yīng)當(dāng)盡量避免使用 Layer 的 border兆蕉、corner羽戒、shadow、mask 等技術(shù)虎韵,而盡量在后臺線程預(yù)先繪制好對應(yīng)的內(nèi)容易稠。

  3. 異步繪制
    參考 ASDK 的實(shí)現(xiàn)原理,實(shí)現(xiàn)了一部分簡單異步繪制的代碼:YYAsyncLayer包蓝。YYAsyncLayer 是 CALayer 的子類驶社,當(dāng)它需要顯示內(nèi)容(比如調(diào)用了[self setNeedDisplay])的時候它會向代理,也就是 UIView 請求一個異步繪制的任務(wù)测萎。在異步繪制的時候亡电,Layer 會傳遞一個 block 回調(diào),繪制代碼可以隨時調(diào)用該 block 判斷繪制任務(wù)是否被取消硅瞧。
    當(dāng) tableView 快速滑動的時候份乒,會有大量的異步繪制任務(wù)提交到后臺線程去執(zhí)行,但是滑動速度過快的時候繪制任務(wù)還沒有完成就已經(jīng)被取消了腕唧,這時候如果繼續(xù)繪制或辖,就會造成大量的 CPU 資源浪費(fèi),甚至阻塞線程并造成后續(xù)的繪制任務(wù)遲遲無法實(shí)現(xiàn)四苇,這樣我們就需要盡量快速孝凌、提前判斷當(dāng)前繪制任務(wù)是否被取消,保證被取消的任務(wù)能及時退出月腋,不至于影響后續(xù)操作。
    目前有些第三方微博客戶端瓣赂,使用了這樣一種方法來避免高速滑動時候 cell 的繪制過程榆骚,相關(guān)實(shí)現(xiàn)見這個項(xiàng)目VVeboTableViewDemo.它的原理是,當(dāng)滑動時煌集,松開手指后妓肢,立刻計(jì)算出滑動停止的時候 cell 的位置,并需要繪制那個位置附近的幾個 cell苫纤,而忽略當(dāng)前滑動中的 cel碉钠。這個方法比較有技巧性,并且對于滑動性來說是很大的提升卷拘,唯一的缺點(diǎn)是快速滑動過程中會出現(xiàn)大量空白的內(nèi)容喊废。如果你不想實(shí)現(xiàn)比較麻煩的異步繪制而又想保證滑動的流程性,這個技巧是不錯的選擇栗弟。

  4. 全局并發(fā)控制
    當(dāng)使用 concurrent queue 來執(zhí)行大量繪制任務(wù)的時候污筷,偶爾會遇到這種問題:



大量的任務(wù)提交到后臺隊(duì)列的時候,某些任務(wù)會因?yàn)槟承┰颍ù颂幨?CGFont鎖)被鎖住導(dǎo)致線程休眠乍赫,或者被阻塞瓣蛀。concurrent queue 隨后會創(chuàng)建新的線程來執(zhí)行其他任務(wù)陆蟆。當(dāng)這種情況多變時,或者 App 中使用了大量 concurrent queue 來執(zhí)行較多任務(wù)時惋增,App 在同一時刻就會存在幾十個線程同時運(yùn)行叠殷、創(chuàng)建、銷毀诈皿。CPU 是用時間片輪轉(zhuǎn)來實(shí)現(xiàn)線程并發(fā)的溪猿,盡管 concurrent queue 能控制線程的優(yōu)先級,但大量線程同時操作的時候纫塌,這個操作仍然會擠占掉主線程的 CPU 資源诊县。ASDK 有個 Feed 列表的 Demo:SocialAppLayout,當(dāng)列表內(nèi) cell 過多,并且非炒胱螅快速的滑動的時候依痊,界面仍然會出現(xiàn)少量卡頓,就是這個原因造成的怎披。
使用 concurrent queue 時不可避免的會遇到這種問題胸嘁,但當(dāng)使用 serial queue 又不能充分發(fā)揮多核 CPU 資源,有一個簡單的工具: YYDispatchQueuePool 為不同優(yōu)先級創(chuàng)建和 CPU 數(shù)量相同的 serial queue 凉逛,每次從 pool 中取 queue 的時候性宏,會輪詢返回其中的一個 queue∽捶桑可以把 App 內(nèi)所有的異步操作毫胜,包括圖像解碼、對象釋放诬辈、異步繪制等酵使,都按照優(yōu)先級的不同放入了全局的 serial queue 中執(zhí)行,這樣盡量避免了過多線程導(dǎo)致的性能問題

  1. 更高效的異步圖片加載
    SDWebImage 有時候仍然會產(chǎn)生少量的性能問題焙糟,并且有地方不能滿足需求口渔,所以這時候需要實(shí)現(xiàn)一個性能更高德圖片加載庫。在顯示單張圖片的時候穿撮,利用 UIView.layer.contents 就足夠了缺脉,沒有必要使用 UIImageView 帶來額外的資源消耗,為此可以在 CALayer 上添加 setImageWithURL: 等方法悦穿。除此之外攻礼,還可以把圖片解碼等操作通過 YYDispatchQueuePool 進(jìn)行管理,控制 App 總線程數(shù)量咧党。

  2. 其它可以改進(jìn)的地方

  3. 列表中不需要響應(yīng)觸摸事件的控件可以事先用 ASDK 的圖層合成技術(shù)預(yù)先合為一張圖秘蛔,

  4. 進(jìn)一步減少每個 cell 內(nèi)部圖層的數(shù)量,用 CALayer 替換掉 UIView。

  5. 將 cell 按類型劃分深员,進(jìn)一步減少 cell 內(nèi)部不必要的視圖對象和操作

  6. 把需要放到主線程的任務(wù)劃分為足夠小的塊负蠕,并通過 Runloop 來進(jìn)行調(diào)度,在每個 loop 中判斷下一次 Vsync 時間倦畅,并在下次 Vsync 到來之前遮糖,把當(dāng)前未執(zhí)行完的任務(wù)延遲到下一個循環(huán)中去。

  7. 如何評測界面的流暢度
    過早的優(yōu)化是萬惡之源叠赐,在需求未定欲账、性能問題不明顯時,沒有必要嘗試進(jìn)行優(yōu)化芭概,而是要盡量正確的實(shí)現(xiàn)功能赛不。在做性能優(yōu)化的時候,也最好走 修改代碼->profile->修改代碼這樣一個流程罢洲,優(yōu)化最值得優(yōu)化的地方踢故。
    如果你需要一個明確的 FPS 指示器,可以嘗試一下 KMCGeigerCounter,對于 CPU 的卡頓惹苗,它可以通過內(nèi)置的 CADisplayLink 檢測出來殿较;對于 CPU 帶來的卡頓,它用了一個1X1 的 SKView 來進(jìn)行監(jiān)視桩蓉。這個項(xiàng)目有兩個小問題:SKView 雖然能監(jiān)視到 GPU 的卡頓淋纲,但是引入 SKView 本身就會對 CPU/GPU 帶來一些額外的資源消耗;而且這個項(xiàng)目在 iOS 下會有一些額外的兼容問題院究。
    這個 FPS 指示器 YYFPSLabel 雖然只有幾十行代碼洽瞬,僅用到了 CADisplayLink 來監(jiān)視 CPU 的卡頓問題,但是可以滿足日常需要儡首。
    最后使用 Instument 的 GPU Driver 預(yù)設(shè)片任,能夠?qū)崟r查看到 CPU 和 GPU 的資源消耗。早這個預(yù)設(shè)內(nèi)蔬胯,你可以看到所以與現(xiàn)實(shí)有關(guān)的數(shù)據(jù),比如 Texture 數(shù)量位他、CA 提交的頻率氛濒、GPU 消耗等,在定位界面卡頓的問題的時候鹅髓,這是最好的工具舞竿。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市窿冯,隨后出現(xiàn)的幾起案子骗奖,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件执桌,死亡現(xiàn)場離奇詭異鄙皇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)仰挣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門伴逸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人膘壶,你說我怎么就攤上這事错蝴。” “怎么了颓芭?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵顷锰,是天一觀的道長。 經(jīng)常有香客問我亡问,道長官紫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任玛界,我火速辦了婚禮万矾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘慎框。我一直安慰自己良狈,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布笨枯。 她就那樣靜靜地躺著薪丁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪馅精。 梳的紋絲不亂的頭發(fā)上严嗜,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機(jī)與錄音洲敢,去河邊找鬼漫玄。 笑死,一個胖子當(dāng)著我的面吹牛压彭,可吹牛的內(nèi)容都是我干的睦优。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼壮不,長吁一口氣:“原來是場噩夢啊……” “哼汗盘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起询一,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤隐孽,失蹤者是張志新(化名)和其女友劉穎癌椿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體菱阵,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡踢俄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了送粱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片褪贵。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖抗俄,靈堂內(nèi)的尸體忽然破棺而出脆丁,到底是詐尸還是另有隱情,我是刑警寧澤动雹,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布槽卫,位于F島的核電站,受9級特大地震影響胰蝠,放射性物質(zhì)發(fā)生泄漏歼培。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一茸塞、第九天 我趴在偏房一處隱蔽的房頂上張望躲庄。 院中可真熱鬧,春花似錦钾虐、人聲如沸噪窘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倔监。三九已至,卻和暖如春菌仁,著一層夾襖步出監(jiān)牢的瞬間浩习,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工济丘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谱秽,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓摹迷,卻偏偏與公主長得像弯院,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泪掀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

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