I've been running down slow scroll performance and I've noticed that when I scroll and setImage
gets called with non-cached images, the performance lags while the download happens.
if let imageURL = URL(string: presentable.imageUrl) {
let resource = ImageResource(downloadURL: imageURL)
photoView.kf.setImage(with: resource, options: [.transition(.fade(0.2))])
}
My understanding is that Kingfisher downloads these on a background thread and then displays them on the main thread but the main thread seems to be temporarily blocked. Removing the .transition
doesn't help the situation.
Any ideas on how to improve my scroll performance? Thanks
When the images are larger than the image view, iOS needs to manipulate large UIImage
objects, which can cause observable stuttering in the UI. You can prevent that problem by resizing the images before using them.
Fortunately, Kingfisher has a processor that can resize these (in a background thread) for you. As the Cheat Sheet says:
Using
DownsamplingImageProcessor
for high resolution imagesThink about the case we want to show some large images in a table view or a collection view. In the ideal world, we expect to get smaller thumbnails for them, to reduce downloading time and memory use. But in the real world, maybe your server doesn't prepare such a thumbnail version for you. The newly added
DownsamplingImageProcessor
rescues [sic]. It downsamples the high-resolution images to a certain size before loading to memory:imageView.kf.setImage( with: resource, placeholder: placeholderImage, options: [ .processor(DownsamplingImageProcessor(size: imageView.size)), .scaleFactor(UIScreen.main.scale), .cacheOriginalImage ])
Typically,
DownsamplingImageProcessor
is used with.scaleFactor
and.cacheOriginalImage
. It provides a reasonable image pixel scale for your UI, and prevent future downloading by caching the original high-resolution image.
I created a little test with small images and confirmed that it was silky smooth, but when I used large images, I experienced stuttering in the scrolling behavior. But when I added this DownsamplingImageProcessor
in the large image scenario, it was silky smooth again.
Updating
self.imageView.contentMode = .scaleAspectFill
to
self.imageView.contentMode = .scaleAspectFit
did the trick for me.
I have embedded UICollectionView
inside UITableViewCell
. Each UICollectionViewCell
has an image view which loads image from URL using Kingfisher. My table view scrolling was a lot jerky and I tried different things including not to bind model and setting data to each cell. But nothing made any difference whatsoever. Once I changed content mode of image view, it is now scrolling very smoothly.
As per Rob's answer, it is also possible that setting mode to .scaleAspectFill
might be required to do some processing even-though the image size is smaller (even 480 x 320 in my case). After updating mode to .scaleAspectFit
, now its scrolling smoothly even for large-sized images.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With