iOS首頁渲染優化 -- imageName:

窗前有月光發表於2018-12-16

前言

隨著APP功能的逐漸強大和業務上的逐漸完善,目前對於iOS開發者來說,對於APP的優化逐漸顯得尤為重要,本篇基於APP渲染優化上探討一下imageName:的愛恨情仇,下面以UITabBarItem渲染圖片為例,一步步以實踐的方式進行分析。

分析

首先看下未優化前的效果圖:

測試裝置:iPhone7 ,系統:12.1

iOS首頁渲染優化 -- imageName:

細心的同學應該能夠發現,在登入進入首頁,到首頁渲染結束,中間會有一段白屏,為什麼會白屏一會而沒有馬上渲染首頁呢,第一感覺肯定是這中間形成主執行緒阻塞了,讓UI沒有立即渲染出來,其實事實上確實是這樣,那接下來我們通過Instruments分析一下哪裡執行了耗時操作以至於首頁渲染被阻塞了。Instruments裡面有個工具TimeProfiler,可以用來幫我們檢視哪裡有耗時操作。關於這個工具的使用和配置網上很多介紹本篇不做重點分析了,我直接粘除錯的圖片了。

iOS首頁渲染優化 -- imageName:

通過TimeProfiler的結果一目瞭然,在CustomTabBarItem裡面做了什麼用了387ms。可以在工具裡面直接右鍵進入到到這段耗時程式碼的位置。我總共測試了五個tabbar渲染item圖片的耗時:

iOS首頁渲染優化 -- imageName:
iOS首頁渲染優化 -- imageName:

看打點日誌就很恐怖了,執行兩個imageName:就消耗了主執行緒差不多100ms的時間,五個tabbar那就是500ms的時間,顯然這就是上面效果圖出現白屏的原因了,實際上imageName:是會對圖片進行解碼之後再渲染的。

既然原因找到了,那就嘗試解決一下。將這個耗時的操作放到子執行緒執行,這裡也是參考了SDWebImage的圖片編解碼的思路,SD在拿到圖片data的時候並沒有將它直接轉為image物件,而是在子執行緒裡面做了一個解碼的操作,這樣已經被解碼的圖片就賦值給imageView的時候就不會再進行解碼,也就不會妨礙主執行緒了。

- (void)decodedImageWithImageName:(NSString *)imageName block:(void(^)(UIImage *image))block {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        @autoreleasepool{
            UIImage *image = [[UIImage imageNamed:imageName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
            image = [UIImage decodedImageWithImage:image];
            dispatch_async(dispatch_get_main_queue(), ^{
                if(block)
                block(image);
            });
        }
    });
}
複製程式碼

程式碼實現很簡單,就是將圖片的操作放入到一個全域性佇列中,當然也可以自己建立一個佇列去執行這個非同步操作。decodedImageWithImage:為SD的程式碼,需要#import "SDWebImageDecoder.h",具體實現網上對這一塊的原始碼解釋的比較多,很容易理解。

這樣我們的圖片經過這層處理之後,我們再來看一下優化之後的效果:

iOS首頁渲染優化 -- imageName:
從總計500ms降到了6ms,基本可以忽略不及了,我們再在真機上面看一下優化後的效果:

iOS首頁渲染優化 -- imageName:

經過同事的提醒和評論區小夥伴的質疑,我又重新測試了一下imageName:的載入耗時,得到一種現象,如果將圖片資源放入在檔案目錄中,每張圖片第一次載入依舊耗時大概30ms左右,因為imageName:方法對圖片有快取,所以測試多次載入需要多張不同的圖片進行測試。另外我將測試圖片放入Assets.xcassets中每張圖片載入耗時大概在1ms左右,猜測Assets.xcassets提前將圖片做了快取。

測試圖片:

iOS首頁渲染優化 -- imageName:

總結

通過上面的分析,實際上imageName:這樣的UI函式我們天天都在用,但是從沒想過它在某些地方能產生這麼大的影響。問題的定位和解決其實都很簡單,但是這種簡單的問題往往會被我們開發者忽略掉,產生一些不好的結果,值得反思。

相關文章