思维脑图:请点击查看图片框架.xmind
流程图:请点击查看图片框架.graffle
一、图片优化
1、图片体验优化
1.1、图片占位图、异常图
1.2、图片加载动画
可适当在图片视图本身加入loading动画
2、图片内存优化
3、降低图片质量(缩略图/数据万象)
注意:图片所占内存的大小与图片的尺寸有关,而不是图片的文件大小
3.1、使用缩略图
让后台返回缩略图地址,而不是大图地址
3.2、图片数据万象及其优化\根据视图大小,获取保持比例的合适目标图片(完整图)
后台不是给缩略图地址的情况下,自己通过图片地址,配置对应的参数,来展示。
图片数据万象的优化,请继续查看下文 数据万象/根据视图大小,获取保持比例的合适目标图片(完整图)
4、图片缓存
3.1、直接图片视图加载
3.2、先加载图片数据,再赋值到图片视图上
3.3、去除多余的图片切换动画
5、提前解压缩
图片解压缩的过程其实就是将图片的二进制数据转换成像素数据的过程。
图片的解压缩是一个非常耗时的 CPU 操作,并且它默认是在主线程中执行的。那么当需要加载的图片比较多时,就会对我们应用的响应性造成严重的影响,尤其是在快速滑动的列表上,这个问题会表现得更加突出。这就是 UIImageView 的一个性能瓶颈。
-
由于UIImage的imageWithData函数是每次画图的时候才将Data解压成ARGB的图像,
所以在每次画图的时候,会有一个解压操作,这样效率很低。为了提高效率,通过SDWebImageDecoder将包装在Data下的资源解压,然后画在另外一张图片上,这样这张新图片就不再需要重复解压了。
二、数据万象/根据视图大小,获取保持比例的合适目标图片(完整图)
内存大小的计算:内存大小=宽度×高度×每像素字节数
对ARGB来说,每个像素有4个通道,每个通道1个字节,即其每个像素需要4个字节
对SRGB来说,其每个像素也是4个字节。(虽然其不包含Alpha通道,但存储时仍然可能按照每个像素4字节来处理,以保持数据对齐和优化内存访问。)
1、背景
在服务端,我们保存的是图片的原图。但实际在app使用过程中,我们常常只需要该图的缩略图。那么如何及合理的得到我们想要的缩略图呢?
2、改进前
2.1、方法
缩略图的获取,最基本的方法是使用数据万象提供的接口,通过为其添加尺寸参数,即可得到缩略图片。
添加后的缩略图地址形如:https://www.demo.com/1.jpg?width=44&height=44
2.2、存在的问题
使用上述方法,我们虽然得到了自适应每个image图片视图自身大小的缩略图。
但同时也引入了另一个问题:就是如果某张图需要出现在不同大小的image视图中,则我们会下载及缓存多份数据。这无形中增加了①流量的消耗、②手机存储空间的消耗;③同时也因为认为要下载新缩略图,而导致无法使用就近的缩略图。所以我们需要改进。
示例:
1 | 优化前:在 44*44 和 50*50 大小的视图区域上的图片地址分别如下: |
3、改进后
3.1、改进方法
改进方式,在进行万象拼接前,我们通过提前新增缩略图梯度,将相近大小的缩略图归为使用同一张。
梯度的层数,可根据自己实际项目图片规范设计。
举例:以宽为 375pt 的手机屏幕为例。假设你图片规范是 [ 64pt 、188pt、375pt ]。
则当你的视图是 100pt 和 120pt 的视图都使用 188pt 的图片。
3.2、改进的好处
通过上述方法,我们能够达到①减少流量的消耗、②减少手机存储空间的消耗;③同时使得对于同一图片在相近大小的image图片视图的地方,由于计算出的缩略图处在同一梯度,而可以不用重新下载等待,而是直接使用缓存渲染,从而大大提升了用户体验。
4、流程
4.1、主要流程
获取梯度范围 -> 完成万象拼接
4.2、主要流程图
以下为”获取梯度范围”的流程
图片的更多完整流程图,请查看 图片框架.graffle
三、图片高磁盘占用的排查与优化
文档:《高磁盘占用的排查与优化.md》
四、图片展示
1、竖直滚动列表上的图片展示
2、图片大图浏览

图片来源:图片框架.xmind
附1:图片优化的相关代码
1、图片占位图、异常图
1 | return CachedNetworkImage( |
2、图片加载动画
可适当在图片视图本身加入loading动画
1 | return CachedNetworkImage( |
3、图片缓存
3.1、直接图片视图加载
1 | TolerantNetworkImage( |
3.2、先加载图片数据,再赋值到图片视图上
eg:首页频道图片切换
1 | // 定义 |
3.3、去除多余的图片切换动画
eg:许个愿图片切换
1 | return CachedNetworkImage( |