关于 Fresco 和 Glide,真的和你想的一样吗

2,449 阅读4分钟

网上对于 Fresco 的讨论一般都是说 Fresco 性能更好,Glide 使用更简单。然而这个问题的答案真的有那么明显吗?

比如性能问题。Fresco 性能真的比 Glide 好多少吗?毕竟 Fresco 包更大,线程开得也更多,图片重采样也要手动提供 ResizeOptions。此外,Fresco 分配用于缓存的内存也更大,如果不是主动指定 Bitmap.Config 否则不会启用 HARDWARE 格式。其中,我最介意的是必须要手动提供 ResizeOptions 才能执行重采样,但往往需要手动执行的都是不靠谱的,如果开发人员素质不够,或者没注意,那么在加载大图时就很容易导致内存问题。所以,从性能的角度上说,特别如果是面向 5.0 以上的设备,个人认为 Glide 反而更好用、更安全一些。

而与此同时,Glide 的使用真的比 Fresco 更简单吗?的确,如果要使用 Java 代码自定义图片请求,那么,Fresco 的确比 Glide 复杂很多。然而,大多数情况下,Fresco 使用 SimpleDraweeView 即可完成图片请求,同时附加圆角、placeholder、宽高比等功能,如果自定义一个通用的 style,Fresco 代码量反而能够比 Glide 少很多。而 Glide 则每次都要 with、load、into,宽高比等功能也要自己实现,圆角的功能也不支持自定义上下左右不同位置使用不同的半径,还要自己创建一个 RoundedCorners 对象,而不是直接设置即可,代码写起来反而更麻烦一些。

总的来说,Fresco 功能更丰富,比如圆角、宽高比、渐进式加载 JPEG、在加载过程中显示进度条、加载失败后点击重试等,对 5.0 以下的手机支持也更好。而 Glide 更方便,比如自动根据 ImageView 尺寸缩放图片、在内存事件回调时自动释放内存等。而对于性能以及使用的问题,答案可能并没有网上讨论的那么简单,还需要自行权衡。

FrescoGlide
代码结构相对更复杂难懂相对更清晰直观
View自定义的 DraweeView配合 ImageView 使用
获取 Bitmap稍显复杂,需要向 ImagePipeline 发送自定义请求相对更简单,使用 CustomTarget 或 FutureTarget 即可
缩放方式更多,但默认不执行重采样,需要手动设置为 true,并提供 RezieOptions默认自动根据 ImageView 的尺寸对图片进行重采样
图层层级更多,功能更丰富(比如显示进度条、点击重试等)分为占位图、缩略图、加载失败占位图三层
图片格式支持 gif、webp、视频缩略图,可添加自定义 svg 解码器支持 gif、webp、svg、视频缩略图
变换操作支持圆形、圆角、旋转等支持圆形、圆角、旋转等,但不支持在不同位置使用不同的圆角半径
渐进加载 JPEG支持不支持
缓存1) 内存缓存(活跃、非活跃)2) 未解码的图片缓存(字节流)3) 磁盘缓存(缓存的是原始图像数据,可以手动设置小文件、大文件分开存储,但需要手动指定哪些是小文件)1) 内存缓存(活跃、非活跃) 2) 磁盘缓存(解码、变换后的图像数据) 3) 磁盘缓存(原始图像数据)
缓存大小1) 内存缓存一般是 ActivityManager.getMemoryClass / 4 2) 未解码的图片缓存一般是 4MB 3) 磁盘缓存一般是 40MB1) 内存缓存根据手机分辨率计算,一般是分辨率乘以 2 2) 磁盘缓存默认 250MB(两级缓存共用)
缓存算法LRU(磁盘缓存通过修改文件 LastModified 属性实现)LRU(磁盘缓存通过 DiskLruCache 实现)
对象池都有 Bitmap 对象池和数组对象池
内存事件需要手动调用 trim 方法释放内存监听了 ComponentCallbacks2,可自动释放内存
生命周期监听 DraweeView 的 attach、detach 事件添加 Fragment 监听生命周期
线程池线程池更多,线程数也更多主要有 3 个线程池,线程数相对较少
Bitmap 格式默认为 ARGB_8888,可以手动设置为 HARDWARE优先使用 Config.HARDWARE(8.0),否则默认使用 ARGB_8888
Bitmap 存储5.0 以下使用 native 内存存储,5.0 及以上使用 Java 堆存储Bitmap 优先使用 GPU 存储(8.0),否则使用 Java 堆存储