高清大圖加載優化

高清大圖加載的問題

以前在項目中遇到了加載高清大圖的場景,處理很差佔用大量內存,形成性能問題,影響用戶體驗。ios

如何去解決加載高清大圖這個難點呢?先看看iOS中的圖片加載流程。git

iOS中圖片的加載流程

國外有文章對圖片的工做流寫的很清楚,這裏是連接github

簡單來講是三步:bash

  • 一、加載圖片數據,這裏的圖片數據還沒有解碼
  • 二、解碼圖片數據
  • 三、渲染圖片

性能問題的通常是發生在解碼圖片這個步驟上,SDWebImage是提早強解碼圖片,這樣在渲染時就不會再發生解碼,其強解碼的代碼是在SDWebImageCoderHelper中的decodedImageWithImage函數中CGImageRef imageRef = [self CGImageCreateDecoded:image.CGImage];app

用SDWebImage能解決嗎?

先說結論:不能。ide

測試SDWebImage的代碼以下:函數

imageView.sd_setImage(with: url!) { (image, error, cacheType, theUrl) in
            print(image?.size)
        }
複製代碼

使用Instruments能夠看出SDWebImage的內存佔用很是大,加載測試圖這樣圖片內存佔用達到270MB,峯值內存達到800MB+。性能

能夠看出,SDWebImage沒法解決高清圖內存佔用太高和內存峯值太高的問題。測試

優化的思路

SDWebImage加載高清圖的性能問題,主要是其直接加載高清圖的原來尺寸致使的,而加載一張圖片的內存佔用 = 圖片Width * 圖片Height * 4。因此直接加載測試圖的原始分辨率的內存佔用是 7033 * 10100 * 4 / (1024 * 1024) = 約270MB優化

所以,對於高清圖的加載,須要採用縮減分辨率的方法來減輕加載的內存壓力,這裏使用DownSampling的方法,具體的方法介紹看WWDC2018-最佳圖像實踐這個Session。

DownSampling的具體原理是,在圖像解碼以前加入建立縮略圖的過程,對加載的Image進行預處理,減小解碼後的Image Buffer的大小,從而減小加載的內存佔用和內存峯值。

這是DownSampling的示例代碼:

func downsample(imageAt imageURL: URL, to pointSize: CGSize, scale: CGFloat) -> UIImage {
    
    //生成CGImageSourceRef 時,不須要先解碼。
    let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
    let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, imageSourceOptions)!
    let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale
    
    //在建立Thumbnail時直接解碼
    let downsampleOptions = [kCGImageSourceCreateThumbnailFromImageAlways: true,
                             kCGImageSourceShouldCacheImmediately: true,
                             kCGImageSourceCreateThumbnailWithTransform: true,
                             kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels] as CFDictionary
    //生成UIImage,強制解碼
    let downsampledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions)!
    return UIImage(cgImage: downsampledImage)
}
複製代碼

這是使用DownSampling優化後的Instrument內存監測:

對比

加載方式 內存佔用 內存峯值
SDWebImage 270MB 800MB+
DownSampling 14MB 40MB

從對比中能夠看出,使用DownSampling能大大下降內存的佔用和峯值。

總結

對於高清大圖的場景來講,內存的佔用尤其重要,如何下降圖片佔用的內存,對提高用戶體驗有着相當重要的做用。從上面的對比中能夠看出,使用SDWebImage是難以應對高清大圖這種場景的,而DownSampling這種縮略圖的方案卻能很好適應這種場景。

參考資料

Image and Graphics Best Practices 談談 iOS 中圖片的解壓縮

相關文章
相關標籤/搜索