主线程在滚动时阻塞以及Kingfisher设置图像

9

我一直在研究缓慢滚动性能,并且注意到当我滚动时,如果使用非缓存图像调用 setImage 函数,则性能会受到下载时间的影响。

if let imageURL = URL(string: presentable.imageUrl) {
    let resource = ImageResource(downloadURL: imageURL)
    photoView.kf.setImage(with: resource, options: [.transition(.fade(0.2))])
}

我的理解是,翠鸟(Kingfisher)在后台线程上下载这些内容,然后在主线程上显示它们,但是主线程似乎暂时被阻塞了。删除 .transition 并不能改善情况。
有什么想法可以提高滚动性能吗?谢谢。

图片加载时滚动出现卡顿,待图片加载完成后恢复正常。我只是使用KF的setImage默认实现,没有做任何自定义。 - Zack Shapiro
图片的大小是否适合图像视图,还是太大了?我可以想象这可能会导致一些轻微的卡顿... - Rob
很可能更大。我无法控制图像大小,这是用户生成的内容。 - Zack Shapiro
1
是的,但你可以在后台调整大小。但我会感到惊讶,因为KingFisher的下载是导致停顿的全部原因。 - Rob
1
那是我的想法。让我先尝试调整大小,然后再交给KF。 - Zack Shapiro
KF有backgroundDecode选项。试试看。 - Ryan
2个回答

19
当图片比图像视图大时,iOS需要操作大的UIImage对象,这可能会导致UI明显卡顿。在使用图片之前,您可以通过调整大小来解决此问题。
幸运的是,Kingfisher有一个处理器可以为您调整大小(在后台线程中)。如“Cheat Sheet”所说:

使用DownsamplingImageProcessor处理高分辨率图像

考虑我们希望在表视图或集合视图中显示一些大型图像的情况。在理想的世界中,我们希望获得更小的缩略图,以减少下载时间和内存使用。但在现实世界中,您的服务器可能没有为您准备这样的缩略图版本。新添加的DownsamplingImageProcessor可以解救它。它会将高分辨率图像降采样到某个大小,然后再加载到内存中:

imageView.kf.setImage(
    with: resource,
    placeholder: placeholderImage,
    options: [
        .processor(DownsamplingImageProcessor(size: imageView.size)),
        .scaleFactor(UIScreen.main.scale),
        .cacheOriginalImage
    ])

通常,DownsamplingImageProcessor.scaleFactor.cacheOriginalImage 一起使用。它为您的UI提供合理的图像像素比例,并通过缓存原始高分辨率图像来防止未来下载。

我创建了一个小图像测试并确认它非常流畅,但当我使用大图像时,我遇到了滚动行为的卡顿。但是,当我在大图像场景中添加了这个 DownsamplingImageProcessor 后,又变得非常流畅了。


在我的情况下,这是真的...我们不应该加载比容器更大的图像。 - NSPratik
1
是的,我们不应该加载比容器乘以设备比例更大的图像(例如,在3×设备上的100×100 pt图像视图,应使用300×300 px的图像)。 - Rob
有时候,内容模式也很重要,请检查我的回答... - NSPratik

0

Updating

self.imageView.contentMode = .scaleAspectFill

to

self.imageView.contentMode = .scaleAspectFit

did the trick for me.

我已经将UICollectionView嵌入到UITableViewCell中。每个UICollectionViewCell都有一个图像视图,它使用Kingfisher从URL加载图像。我的表格视图滚动非常卡顿,我尝试了不同的方法,包括不绑定模型并将数据设置为每个单元格。但是没有任何改变。一旦我改变了图像视图的内容模式,现在滚动非常流畅。
根据Rob的答案,即使图像大小较小(甚至在我的情况下为480 x 320),设置模式为.scaleAspectFill也可能需要进行一些处理。将模式更新为.scaleAspectFit后,现在即使对于大型图像也可以平稳滚动。

有什么想法为什么它有帮助吗? - Legonaftik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接