'iOS Swift Tips for Loading Image Faster
I have PNG images that range from 2MB to 12MB in size. I'm loading one of these images into an imageView using SDWebImage via the following code in my viewDidLoad:
self.imageView.contentMode = UIViewContentMode.ScaleAspectFit
self.imageView.sd_setImageWithURL(NSURL(string: imageURL))
It can take as high as 17 seconds to load this image onto the view. Am I doing something wrong here? I'm only loading one of these images into my view, so I did not think it would take this long. Any other things I can do to load the image faster?
Is the only option creating a smaller image to load?
Solution 1:[1]
Compress the image and load it.. if you are accessing this through network make sure you have enabled caching to make the loading faster
Solution 2:[2]
We have something called intervention that we have at our backend. It provides us with a URL in which we can scale image by providing a width and height after the URL
guard let url = imageURL else { return }
var smallURL = url + "/" + "(20)" + "/" + "(20)"
So, What I do here is that I load the image with size (20x20) first and show it as blurred image and when the image with actual size is loaded I replace it with original Image.
That way it is a good UX because User does not have to wait for the image to load instead it gets a impression that image is loading.
And all these things are done in extension of image view so, you can directly call it as :
imageView.setImage(imageURL: "https://i.stack.imgur.com/GsDIl.jpg")
extension UIImageView {
func setImage(imageURL : String?,size : CGFloat = ScreenSize.width ){
guard let url = imageURL else { return }
var originalURL = url
var smallURL = url + "/" + "\(20)" + "/" + "\(20)"
let actualImageUrl = URL(string: name)
let smallURL = URL(string: smallName)
self.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
self.yy_setImage(with: smallURL, placeholder: nil, options: .showNetworkActivity) { (image, _, _, _, _) in
guard let _ = image else { return }
let blurredImg = image?.applyBlurWithRadius(0.5, tintColor: UIColor.black.withAlphaComponent(0.4), saturationDeltaFactor: 1.0)
self.image = blurredImg
self.yy_setImage(with: actualImageUrl, placeholder: blurredImg, options: .progressiveBlur, completion: { [weak self] (image, url, type, _, _) in
self?.image = image
})
}
}
}
Instead of using SDWebImage I have used YYWebImage it provides more features and It is based on SDWebImage.
Hope it Helps!!
Solution 3:[3]
Some of the other suggestions like caching and blurred image preview are good but I would suggest, in addition, you consider optimizing the images better in the first place.
Check out my answer to a related question about reducing app file size by reducing image size,
PNG files are the preferred image format for iOS but you can also use JPEG taking a small hit in load time but the gain in file reduction often outweighs this by an order of magnitude or more. Basically, if the image contains large regions of continuous tone like photos, then JPEG is likely better. You can play in Photoshop but the $7 (on sale from 14) Lossless Photo Squeezer does a great job with no effort.
Even if PNG you can save size by dropping the bit depth. This is how Loss Photo Squeezer works dropping to 8 bit. If you do not transparency you can drop the alpha channel or if you need limited you can use a 1-bit alpha channel out of photoshop. If you want to go hardcore, it is possible to use 8 bit JPEG with an 8-bit alpha channel. See
http://calendar.perfplanet.com/2010/png-that-works/
You can also play with bit depths lower than 8 for some images.
If you want to go really hardcore consider using WebP. There are a few open source iOS implementations such as https://github.com/seanooi/iOS-WebP
You might also want to look at the resolution. retina images are great for fine detail like text but I often use 1x resolution for images even on a retina display for photographs. This works out well because if you need the resolution to read text than there is a good chance that the PNG will compress very well anyway.
IF you have an image that has aspects of continuous tone appropriate for JPEG and some area such as text that is more appropriate for PNG, you can go crazy and break the image into a JPEG and an 8-Bit PNG with an alpha channel and combine the two images after download.
Solution 4:[4]
If you are trying to download a thumbnail image from the back-end you can try adding the context parameter in your SDWebImage call.
yourImageView.sd_setImageWithURL(withPlaceholder: nil, context: [.imageThumbnailPixelSize: yourThumbnailSize])
Add some constant image thumbnail pixel size as shown above.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Sharath |
| Solution 2 | Agent Smith |
| Solution 3 | Community |
| Solution 4 | iPhoneDeveloper |
