iOS使用Instrument-Time Profiler工具分析和優(yōu)化性能問題

背景

前不久我做了一個(gè)富文本編輯工具苍蔬,編輯器遇到了一個(gè)性能問題是添加多張圖片诱建,當(dāng)滾動(dòng)編輯區(qū)域,遇到圖片切換的時(shí)候會(huì)有明顯的卡頓現(xiàn)象碟绑。這篇文章基于這個(gè)卡頓的性能問題進(jìn)行性能瓶頸的分析以及做對(duì)應(yīng)的優(yōu)化俺猿。

可以打開這個(gè)鏈接 iOS使用UITableView實(shí)現(xiàn)的富文本編輯器 查看我的文章茎匠,這篇文章所用的項(xiàng)目也是基于這個(gè)項(xiàng)目的。

結(jié)果

最終的分析優(yōu)化的結(jié)果把時(shí)間從90ms的數(shù)量級(jí)降低到了2ms的數(shù)量級(jí)押袍,達(dá)到了一個(gè)比較流暢的效果诵冒。具體的分析優(yōu)化步驟請(qǐng)往下看。

問題分析

既然問題是發(fā)生在圖片切換的時(shí)候谊惭,圖片是放在單獨(dú)的一個(gè)Cell中的汽馋,那么就嘗試在Cell的渲染方法
cellForRowAtIndexPath 添加兩個(gè)Log,查看方法執(zhí)行所用的時(shí)間圈盔。

輸入圖片說明

對(duì)應(yīng)的結(jié)果:

2017-08-11 06:12:48.744 RichTextEditDemo[6867:1064632] ======begin render cell
2017-08-11 06:12:48.749 RichTextEditDemo[6867:1064632] ======end render cell
2017-08-11 06:12:49.261 RichTextEditDemo[6867:1064632] ======begin render cell
2017-08-11 06:12:49.266 RichTextEditDemo[6867:1064632] ======end render cell

從日志打印的時(shí)間上看豹芯,大概每渲染一個(gè)Cell只要發(fā)幾毫秒的時(shí)間,貌似問題不會(huì)出現(xiàn)在這個(gè)位置驱敲,然而這并不是真相铁蹈,很明顯的,其他地方不會(huì)影響到众眨,所以得用更高級(jí)的分析工具去分析查看握牧。

發(fā)現(xiàn)問題

Instrument是一個(gè)很好的性能分析工具,可以分析內(nèi)存分配围辙、內(nèi)存泄漏我碟、網(wǎng)絡(luò)情況、CPU占用等和性能有關(guān)的問題姚建,當(dāng)前的性能問題是耗時(shí)的問題矫俺,可以使用 Instrument 的 Time Profiler 進(jìn)行分析
讓這個(gè)列表滾動(dòng),并且有進(jìn)行圖片Cell的切換

圖片列表

可以看到Time Profiler 有下面的記錄掸冤,紅色框中就是Cell切換所耗費(fèi)的時(shí)間值厘托,這個(gè)時(shí)間的增長很明顯的高于其他值了,所以這個(gè)就是我們要定位到的地方了稿湿。

Tips

  • alt + 鼠標(biāo)滾輪 -> 縮放時(shí)間軸
  • shift + 鼠標(biāo)滾輪 -> 移動(dòng)時(shí)間軸
  • 按住鼠標(biāo)框選 -> 選擇和定位時(shí)間軸
Time Profiler 截圖

第一步要在時(shí)間軸上框選一個(gè)范圍铅匹,標(biāo)識(shí)選擇這個(gè)范圍進(jìn)行分析,才能準(zhǔn)確定位到這個(gè)問題饺藤,如圖(1)位置所示包斑;第二步要選在堆棧中的某一個(gè)函數(shù),一般的選擇到OC函數(shù)調(diào)用涕俗,更底層的函數(shù)調(diào)用就到了CF層是C語言實(shí)現(xiàn)的就不好分析了罗丰,所以這里選擇的是 [UIImage drawInRect:blendMode:alpha] 這個(gè)函數(shù)分析,可以看到這個(gè)函數(shù)調(diào)用說花費(fèi)的時(shí)間是 92ms再姑,這是一個(gè)比較長的時(shí)間了萌抵,所以應(yīng)該就是這里導(dǎo)致的卡頓了。

輸入圖片說明

這個(gè)函數(shù)花費(fèi)的時(shí)間和image圖片的大小有關(guān)系的,選擇另一個(gè)時(shí)間峰值范圍绍填,這個(gè)時(shí)間峰值范圍是發(fā)生在小圖之間的切換的

輸入圖片說明

這個(gè)地方耗費(fèi)的時(shí)間就比較小一點(diǎn)霎桅,不過也是達(dá)到了25ms,對(duì)于性能也是有一定的影響的讨永。

解決問題

以上的分析可以得出結(jié)論:[UIImage drawInRect:blendMode:alpha] 函數(shù)的調(diào)用是會(huì)導(dǎo)致性能問題的滔驶,因?yàn)閁ITextView內(nèi)部處理圖片的方式是通過調(diào)用 [UIImage drawInRect:blendMode:alpha] 函數(shù)繪制圖片實(shí)現(xiàn)的。

UITextView內(nèi)部處理圖片

既然是UITextView內(nèi)部的處理方式住闯,所以這個(gè)函數(shù)調(diào)用行為是應(yīng)用層改變不了的瓜浸,不過UIImage對(duì)象是我們可以控制的澳淑,或者可以改變圖片的顯示方式來達(dá)到優(yōu)化的目的比原,所以就有了以下的兩種方案。

方案1

第一種方案就是對(duì)預(yù)覽的圖片進(jìn)行壓縮杠巡,然后再設(shè)置到NSTextAttachmen中量窘,放到UITextView中顯示

textAttachment.image = self.image;
// ===> 修改為
// scaletoSize用于壓縮原始的圖片,textAttachment中的image對(duì)象是壓縮過后的
textAttachment.image = [self.image scaletoSize:showImageWidth];

這樣修改之后大圖的滾到加載時(shí)間減少到了40ms左右

方案1優(yōu)化

雖然減少了一半的時(shí)間氢拥,不過蚌铜,40ms的時(shí)間還是比較長的,下面會(huì)繼續(xù)進(jìn)行優(yōu)化嫩海。

方案2

上面的方案進(jìn)行了圖片的壓縮冬殃,時(shí)間的耗費(fèi)還是因?yàn)?[UIImage drawInRect:blendMode:alpha] 函數(shù)的調(diào)用,所以有沒有一種更好的方案呢叁怪?答案是肯定的审葬,可以把傳給UITextView的image壓縮成一個(gè)很小的,(這一步也可以不必奕谭,傳遞一個(gè)空的UIImageView對(duì)象即可涣觉,這里設(shè)置圖片的主要原因是圖片區(qū)域需要一個(gè)編輯的光標(biāo)),然后在 UITextView 所對(duì)應(yīng)的圖片區(qū)域添加一個(gè)UIImageView血柳,在UIImageView中設(shè)置原始的圖片即可官册,這種方案會(huì)比方案1的效果好很多。
方案二幾個(gè)修改點(diǎn):

  1. 設(shè)置NSTextAttachment的image為空的UIImage對(duì)象
        //....
        NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
        CGRect rect = CGRectZero;
        rect.size.width = showImageWidth;
        rect.size.height = showImageHeight;
        textAttachment.bounds = rect;
        textAttachment.image = [UIImage new];
        
        NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:textAttachment];
        //....
  1. Cell添加ImageView顯示Image
        [self.imageContentView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(self).offset(_imageModel.imageFrame.origin.x);
            make.top.equalTo(self).offset(_imageModel.imageFrame.origin.y);
            make.height.equalTo(@(_imageModel.imageFrame.size.height));
            make.width.equalTo(@(_imageModel.imageFrame.size.width));
        }];

下面是使用方案2優(yōu)化之后的分析圖

優(yōu)化方案2

圖中可以看到 cellForRowAtIndexPath 方法總共占用了2ms的時(shí)間难捌,從分析的堆棧中可以看到 UITextView setAttributedText: 方法才占用了1ms的時(shí)間膝宁,所以這個(gè)提升是很明顯的,因?yàn)閭鬟f了一個(gè)空的UIImageView對(duì)象根吁,不用執(zhí)行 [UIImage drawInRect:blendMode:alpha] 方法员淫,使用了UIImageView直接設(shè)置Image的方式幾乎不會(huì)占用時(shí)間,所以堆棧中看不到 [UIImageView setImage:] 方法調(diào)用的時(shí)間婴栽。

總結(jié)

Instrument是一個(gè)很好工具满粗,你用它可以很方便的幫我們定位到性能問題,問題找到了愚争,那么也就很容易找到解決方案了映皆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挤聘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子捅彻,更是在濱河造成了極大的恐慌组去,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,294評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件步淹,死亡現(xiàn)場(chǎng)離奇詭異从隆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)缭裆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門键闺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人澈驼,你說我怎么就攤上這事辛燥。” “怎么了缝其?”我有些...
    開封第一講書人閱讀 157,790評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵挎塌,是天一觀的道長。 經(jīng)常有香客問我内边,道長榴都,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,595評(píng)論 1 284
  • 正文 為了忘掉前任漠其,我火速辦了婚禮嘴高,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辉懒。我一直安慰自己阳惹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,718評(píng)論 6 386
  • 文/花漫 我一把揭開白布眶俩。 她就那樣靜靜地躺著莹汤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颠印。 梳的紋絲不亂的頭發(fā)上纲岭,一...
    開封第一講書人閱讀 49,906評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音线罕,去河邊找鬼止潮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛钞楼,可吹牛的內(nèi)容都是我干的喇闸。 我是一名探鬼主播,決...
    沈念sama閱讀 39,053評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼燃乍!你這毒婦竟也來了唆樊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,797評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤刻蟹,失蹤者是張志新(化名)和其女友劉穎逗旁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舆瘪,經(jīng)...
    沈念sama閱讀 44,250評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡片效,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,570評(píng)論 2 327
  • 正文 我和宋清朗相戀三年冬筒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了偎捎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剧防。...
    茶點(diǎn)故事閱讀 38,711評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搞乏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚁吝,到底是詐尸還是另有隱情施流,我是刑警寧澤,帶...
    沈念sama閱讀 34,388評(píng)論 4 332
  • 正文 年R本政府宣布某残,位于F島的核電站,受9級(jí)特大地震影響陵吸,放射性物質(zhì)發(fā)生泄漏玻墅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,018評(píng)論 3 316
  • 文/蒙蒙 一壮虫、第九天 我趴在偏房一處隱蔽的房頂上張望澳厢。 院中可真熱鬧,春花似錦囚似、人聲如沸剩拢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽徐伐。三九已至,卻和暖如春募狂,著一層夾襖步出監(jiān)牢的瞬間办素,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評(píng)論 1 266
  • 我被黑心中介騙來泰國打工祸穷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留性穿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,461評(píng)論 2 360
  • 正文 我出身青樓雷滚,卻偏偏與公主長得像需曾,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,595評(píng)論 2 350

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

  • 一. 如何讓你的應(yīng)用程序更加省電呆万?答:(1). 如果程序用到定位刻蚯,需要在定位完畢之后關(guān)閉定位,或者降低定位的頻率桑嘶,...
    Hevin_Chen閱讀 1,133評(píng)論 0 4
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫炊汹、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,066評(píng)論 4 62
  • 關(guān)于iOS掃描二維碼的功能實(shí)現(xiàn)有兩個(gè)常用的第三方庫:ZBar/ZXing,iOS7以后有一個(gè)AVFoundatio...
    靜心凈心閱讀 1,835評(píng)論 1 3
  • 熹朦是個(gè)畫面死忠黨以政, 對(duì)很用心畫面很好的游戲沒有任何抵抗力霸褒, 但是好東西不能自己留著, 所以盈蛮, 在安利之前废菱, 先給...
    熹朦閱讀 803評(píng)論 0 0