🐻优化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缓解内存压力的方法是可行的。

相关推荐
Java中文社群2 分钟前
快看!百度提前批的面试难度,你能拿下吗?
java·后端·面试
小高0071 小时前
🚀Promise 全家桶:原理、实现、API、实战,一篇搞定
前端·javascript·面试
MrSkye2 小时前
🔥披萨还没到你就吃了?”JavaScript异步编程入门全解🔥
前端·javascript·面试
码出极致3 小时前
ZGC 执行日志:解锁低延迟运行的核心密码
面试
北京_宏哥3 小时前
🔥《刚刚问世》系列初窥篇-Java+Playwright自动化测试-32- 操作日历时间控件-下篇(详细教程)
java·前端·面试
極光未晚3 小时前
Vue 项目 webpack 打包体积分析:从 “盲猜优化” 到 “精准瘦身”
前端·vue.js·性能优化
用户84913717547163 小时前
JDK 17 实战系列(第3期):性能优化与系统增强详解
java·后端·性能优化
OpenTiny社区4 小时前
一文解读“Performance面板”前端性能优化工具基础用法!
前端·性能优化·opentiny
拾光拾趣录5 小时前
🔥FormData+Ajax组合拳,居然现在还用这种原始方式?💥
前端·面试
小白学大数据5 小时前
Java爬虫性能优化:多线程抓取JSP动态数据实践
java·大数据·爬虫·性能优化