UITableView 在移動(dòng)開發(fā)中常常是必不可少的今膊,并且是動(dòng)態(tài)的加載季二,要很好的滾動(dòng)顯示效果谷徙,就必須更多的了解UITableView的實(shí)現(xiàn)機(jī)制拒啰,更好的優(yōu)化。
UITableView的優(yōu)化分兩塊:布局優(yōu)化完慧、渲染優(yōu)化图呢、異步操作。(也可以理解為平衡CPU和GPU的負(fù)載骗随,這就要理解為什么會(huì)造成卡頓的原因了)
一蛤织、布局優(yōu)化
布局優(yōu)化包括:布局優(yōu)化和高度優(yōu)化
1、布局有兩種方式鸿染,第一種是AutoLayout(storyboard指蚜、xib或Masonry),第二種是frame涨椒。使用AutoLayout布局的話可以省去人工計(jì)算成本和靈活多變摊鸡,相對(duì)的就會(huì)增加CPU的負(fù)載,而使用frame對(duì)CPU來說就很簡(jiǎn)單蚕冬,唯一的缺點(diǎn)就是可擴(kuò)展性差免猾。以下是引用Draveness的一張圖,展示兩種布局的性能差別
補(bǔ)充:
(1)在開發(fā)的過程中囤热,本人會(huì)優(yōu)先考慮使用AutoLayout的方式猎提,原因有兩個(gè):第一,AutoLayout布局容易且快旁蔼,在開發(fā)中優(yōu)先考慮就是完成功能锨苏;第二是現(xiàn)在的手機(jī)硬件越來越好,性能堪比電腦棺聊,如果不是特別復(fù)制的界面一般TableView滑動(dòng)的流暢度都是沒問題的伞租。
(2)Frame布局方式页藻,這里特別推薦Yang2333的文章憋沿,他的實(shí)現(xiàn)方式挺新穎的,并且對(duì)于tableView的優(yōu)化方式也是信息量滿滿的
2劲适、高度優(yōu)化
UITableView是UIScrollView的子類祟同,所以也是要計(jì)算其ContentSize,UITableView的contentSize的高度是全部Cell的高度和作喘。設(shè)置UITableView的高度有兩種方式
第一種是直接設(shè)置tableView的屬性rowHeight(這種方式只適合設(shè)置固定高度的Cell,并且也是設(shè)置固定高度的推薦方式)耐亏;
第二種是通過代理方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath.
因?yàn)閁ITableView 實(shí)現(xiàn)機(jī)制的原因徊都,每顯示一個(gè)Cell都需要執(zhí)行N次這個(gè)方法(并且包括顯示在屏幕或還沒顯示的),如果在這個(gè)方法中添加計(jì)算Cell的復(fù)雜算法广辰,可想而知這對(duì)CPU而言是非常重的負(fù)擔(dān)暇矫。優(yōu)化的方向是怎么獲取Cell的高度并減少計(jì)算的難度。
本人的做法:關(guān)于UITableView布局的優(yōu)化择吊,一直都是在使用Masonry和UITableView+FDTemplateLayoutCell兩個(gè)框架李根,對(duì)于一般的項(xiàng)目來說都是沒什么問題的。
UITableView+FDTemplateLayoutCell優(yōu)化原理
補(bǔ)充:
對(duì)于不是固定高度的Cell几睛,這里還有一個(gè)小技巧房轿,對(duì)提高UITableView的流暢度很有幫助的。
在tableView:cellForRowAtIndexPath: 方法中需要為每一個(gè)Cell 調(diào)用一次,它應(yīng)該快速執(zhí)行囱持,要盡可能塊的返回重用Cell實(shí)例夯接。Cell還沒顯示到屏幕上,不再這里執(zhí)行數(shù)據(jù)綁定
tableView:willDisplayCell:forRowAtIndexPath: 在Cell要顯示時(shí)調(diào)用纷妆,在這里執(zhí)行數(shù)據(jù)綁定
補(bǔ)充設(shè)置圓角的正確姿勢(shì):bestswifter
二盔几、渲染優(yōu)化
講渲染優(yōu)化這里有幾個(gè)概念需要先提的:混合操作、離屏渲染掩幢,像素對(duì)齊逊拍。
混合操作
渲染最慢的操作之一,是由GPU完成际邻,我們的目的就是減少混合操作的次數(shù)芯丧。
查看混合操作的方式如下圖
離屏渲染
iOS-離屏渲染詳解
離屏渲染優(yōu)化詳解:實(shí)例示范+性能測(cè)試
關(guān)于離屏渲染上面兩篇文章已經(jīng)寫得很詳細(xì)了,這里再推薦一種查看離屏渲染的調(diào)試技巧世曾,如下圖
像素對(duì)齊
有了Retain屏后缨恒,CocoTouch環(huán)境下,可以使用屏幕點(diǎn)來取代像素了度硝,并且屏幕點(diǎn)可以是浮點(diǎn)值肿轨,
當(dāng)屏幕點(diǎn)是浮點(diǎn)數(shù)時(shí),iOS 將會(huì)執(zhí)行子像素渲染蕊程,這技術(shù)在特定類型的內(nèi)容(如文本)時(shí)很有意義椒袍,但是當(dāng)繪制
平滑直線時(shí)則沒有必要了,這會(huì)讓iOS 執(zhí)行一些不必要的任務(wù)藻茂,從而降低FPS
查看方式:在iOS模擬器上運(yùn)行程序驹暑,在”Debug“菜單中選中”Color Misaligned Image“。
有兩種高亮區(qū)域:品紅色區(qū)域會(huì)執(zhí)行子像素渲染辨赐,而黃色區(qū)域是圖片大小沒有對(duì)齊的情況优俘。
建議:對(duì)所有像素相關(guān)的數(shù)據(jù)做四舍五入處理,包括點(diǎn)坐標(biāo)掀序,UIView的高度和寬度帆焕。
跟蹤你的圖像資源:圖片必須是像素完美的,否則在Retina屏幕上渲染時(shí)不恭,它會(huì)做不必要的抗鋸齒處理叶雹。
還有一個(gè)是opaque值,opaque是一個(gè)渲染性能的開關(guān)標(biāo)識(shí)符换吧,并不代表視圖的透明度(aphal 才是視圖的透明度屬性值)折晦,opaque默認(rèn)值是YES,如果opaque的值為NO沾瓦,則是合成渲染满着,加大了GPU合成計(jì)算視圖顯示的計(jì)算難度谦炒。
第三:異步操作
異步操作主要是為了盡快返回Cell,通常是異步操作讀寫數(shù)據(jù)庫(kù)和網(wǎng)絡(luò)請(qǐng)求风喇。