🐻优化GIF的内存加载

一、内存OOM问题

使用 UIImage.animatedImage(with:duration:) 方法:UIImage 类提供了一个便利的方法来加载并处理 GIF 图像,该方法可以将 GIF 图像转换为 UIImage 的动画表示。这种方法可以有效地管理内存,并且不需要手动处理每一帧的图像。但会存在内存问题,UIImage(contentsOfFile:) 虽然不会立即放入内存中,但显示时还是会加载到内存中。

ini 复制代码
if let gifURL = Bundle.main.url(forResource: "example", withExtension: "gif") {
    let gifData = try? Data(contentsOf: gifURL)
    let gifImage = UIImage.animatedImage(with: gifData)
    imageView.image = gifImage
}

大量的GIF会导致OOM问题,一旦使用超过系统的阈值,就会崩溃。

二、使用FLAnimatedImageView可以有效的解决GIF内存暴涨的问题

  • FLAnimatedImageView 使用渐进式解码:FLAnimatedImageView 使用渐进式解码来加载 GIF 图片。渐进式解码允许在图片尚未完全加载时就开始显示并逐步增加清晰度。这意味着 FLAnimatedImageView 可以在加载 GIF 图片的同时,逐帧渲染和显示动画,而不需要等待整个 GIF 图片加载完成。这对于大型 GIF 图片特别有利,因为可以显著降低首次加载的延迟,并提高用户体验。
  • 内存优化:FLAnimatedImageView 在加载和显示大型 GIF 图片时进行了内存优化。它只会将当前帧所需的数据加载到内存中,并在显示下一帧时释放之前的帧数据,从而避免占用过多的内存。这有助于在加载大型 GIF 图片时降低内存使用,减少内存压力和 OOM 问题。

三、让FLAnimatedImageView支持网络GIF

FLAnimatedImageView 是用于显示 GIF 动画的 FLAnimatedImage 库中的特殊控件,它并不直接用于加载网络图片,但我们可以扩展方法为其增加加载网络图片的功能。

swift 复制代码
import FLAnimatedImage
import Kingfisher

extension FLAnimatedImageView {
    func setGifImage(withURL url: URL) {
        // 使用 Kingfisher 加载网络图片
        self.kf.setImage(with: url, completionHandler: { result in
            switch result {
            case .success(let value):
                // 成功加载图片,value.image 是 UIImage 类型
                // 将加载的图片转换为 FLAnimatedImage 类型
                let animatedImage = FLAnimatedImage(animatedGIFData: value.image.kf.gifRepresentation())
                // 在 FLAnimatedImageView 中显示 GIF 动画
                self.animatedImage = animatedImage
            case .failure(let error):
                // 加载图片失败,处理错误
                print("Error loading image: (error)")
            }
        })
    }
}

上述方法利用Kingfisher不仅添加了缓存,还能后直接显示来自网络的GIF图片。

四、测试效果

总体内存可以降低70%,CPU在迅速滑动时波动较大,大概为原来的1-2倍,但是停止滑动时降低为原来的50%左右。由于目前iPhone手机的CPU普遍较好,而内存较低;所以这种用CPU缓解内存压力的方法是可行的。

相关推荐
青莲84317 小时前
Java并发编程高级(线程池·Executor框架·并发集合)
android·前端·面试
冻梨18 小时前
深入解析长列表性能优化方案
性能优化
卓码软件测评18 小时前
CMA/CNAS双资质软件测评机构【Apifox高效编写自动化测试用例的技巧和规范】
测试工具·ci/cd·性能优化·单元测试·测试用例
廋到被风吹走19 小时前
【Java】新特性最佳实践:避坑指南与性能优化
java·性能优化
洛小豆19 小时前
她问我:服务器快被垃圾文件塞爆了,怎么破?我说:给文件办个“临时居住证”
后端·面试
洛小豆20 小时前
孤儿资源治理:如何优雅处理“上传了但未提交”的冗余文件?
java·后端·面试
a努力。20 小时前
中国电网Java面试被问:分布式缓存的缓存穿透解决方案
java·开发语言·分布式·缓存·postgresql·面试·linq
码农水水20 小时前
美团Java后端Java面试被问:Kafka的零拷贝技术和PageCache优化
java·开发语言·后端·缓存·面试·kafka·状态模式
爱可生开源社区20 小时前
MySQL 优化从库延迟的一些思路
数据库·mysql·性能优化
芒克芒克20 小时前
深入浅出JVM的运行时数据区
java·开发语言·jvm·面试