Files
knowledge-kit/Chapter1 - iOS/1.90.md

2.5 KiB
Raw Blame History

YYImage 框架原理,探索图片高效加载原理

图片显示流程

image-20200813130942777

UIImage *image = [UIImage imageNamed:@"test"];
_imageView.image = image;

上述的代码叫做“隐形解码”。 代码测试一张图片从磁盘读取到内存中,通过 Instrucments 中的 Time Profiler 分析得到,从磁盘调用 ImageIO 中方法加载到内存中,这个过程比较耗时。

图片大,则需要更大的空间去将 Data Buffer 计算得到 Image Buffer

所以将图片解码过程,放到异步线程中去。

YYImage 源码

image-20200813131944130

很多框架使用锁都是 pthread_mutex_lock分析原因

pthread_mutex_lock

pthread_mutex_unlock

内存方面

图片相关小建议 目前对于大图片没有特别好的方法进行内存峰值的控制 内存峰值:解码一瞬间带来的内存压力,无关最终图片可能缩放的大小

  1. 下发图片不要太大,字节内部大多数直接接入 ImageX 可以直接控制, 图片下发尽可能不要超大类型的图片,这样对客户端下载和解码带来的压力都不低 ( 字节ImageX 外部也可接入服务 )
  2. 大部分主流图片库支持 Force Redraw 概念,默认都是开启的 ForceRedraw 开启3倍内存峰值提升FPS ForceRedraw 关闭2倍内存峰值直到需要图片才进行渲染降低 FPS ( 字节图片库可以指定是否开启 )
  3. 如果是用户上传的图片,可以选择显示图片大小有一定范围,比如最大不超过 1920x1080 否则本地进行图片缩小后上传
  4. 部分低端机可以增加更多的解码限制,举例: iPhone6 内存大小为 1GBiPhone6s 内存大小为 2GB 对于 iPhone6 而言,一张 4000x6000或着三张 1920x1080同时解码就是压力的极限 对于 iPhone6s 而言,两张 4000x6000或着五张 1920x1080同时解码就是压力的极限 ( 字节图片库支持提前获取图片大小,然后让选择是否解码图片的功能 )
  5. 图片解码后可以进行降采样 虽然无法控制解码当时的内存峰值,但是对于解码后的图库可以进行缩放, 例如在一个 100x100 的UIImageView 里展示一张 4000x6000的图片显然非常浪费 ( 字节的图片库也支持自动降采样操作 )