You need to enable JavaScript to run this app.
导航
iOS 最佳实践
最近更新时间:2021.02.23 10:42:28首次发布时间:2021.02.23 10:42:28

图片SDK我们在历史和对接过程和使用过程中总结了最佳使用实践,供参考使用;

下载耗时优化

图片的下载耗时主要在 建立连接下载 两个阶段,可以通过连接复用优化建立连接的耗时、使用webp、heif、heic等图片格式来减小文件大小优化下载耗时

http2 + https 连接复用优化

  • 通过 网络优化开启 http2 + https,虽然 https 建立连接的耗时较长,但可以通过收敛业务的图片域名,提高链接的复用率,同时 http2 可以提高图片下载速度,最终对图片的加载速度是有一定优化的。

  • 我们在不同业务做过实验,若连接复用率上达到了95%+,则其他各项指标也都比较靠前,解码失败率基本为0%,具备一定的抗劫持能力。

图片格式优化(webp、heif)

  • 静图 webp、heif 格式、动图awebp 能够压缩更小的图片体积,虽然复杂的图片格式可能带来解码耗时微弱增加,但与下载耗时的优化相比,总的图片加载耗时大大缩短。

  • 实验数据显示最终加载耗时对比:静图:heic  < webp < jpeg < png  动图:heif< awebp < gif

接入方式优化

最佳方案是先接入统计能力中的业务标示 biz_tag,通过这种方式,可以知道 app 中的格式分布、业务方的格式分布,从而去推动格式改造,事半功倍。

request.bizTag = @"feed"; //在不同业务的请求设置一个标识业务的字符串,如“feed”、“detail,通过这种设置可以在数据统计指标中看到不同指标的拆分信息;
   
体验优化

1. ​动图边下边播

  • 正常情况下,图片下载100%之后,才进行解码和图片渲染。而开启渐进式之后,会每下载一个百分比的数据就尝试进行解码,如果解码成功就开始进行渲染。所以开启渐进式之后,用户可以更快看到首帧图片,提供一个类似网页加载图片的体验。

​接入方式

因为默认​jpg​等图片是从上到下显示的方式来渐进式加载,用户体验并不佳;而动图可以快速显示首帧,大大提升了用户体验。如果动图也采用​webp​格式,与​gif​相比,将节省30%的带宽。

  • 对动图进行边下边播,使用​BDImageAnimatedImageProgressiveDownload​选项
[imageView bd_setImageWithURL:[NSURL URLWithString:@"https://ws4.sinaimg.cn/large/006tKfTcly1fnl3r44e79g30am062qv8.gif"] options:BDImageAnimatedImageProgressiveDownload];

2. ​下载排队优化

  • 之前在排查问题的时候发现,在 App 启动时发现很多业务会为了提高图片的加载速度,使用预加载先把图片拉下来,但是因为图片库内部只有一个队列对下载任务进行调度,就可能存在因为预加载的图片太多,导致阻塞了正常图片的下载请求。

​接入方式

  • 使用​BDImageRequestDefaultPriority​、​BDImageRequestLowPriority​、​BDImageRequestHighPriority​来控制下载请求的优先级。

  • 现在已经提供了一个开关并且默认打开,将所有的预加载请求优先级设置为​BDImageRequestLowPriority

[BDWebImage shareManager].isPrefetchLowPriority = YES;

​性能优化

​图片降采样

  • 图片有各种分辨率和大小。在很多情况下,它们的大小超过了 app 的要求。例如,一张 200 * 200 的图片加载到一个 100 * 100 的 ImageView 上,不会带来任何明显的好处,不仅会占用宝贵的内存,而且会因为额外的动态缩放而产生额外的性能开销。

  • 当 View 的宽高比图片的宽高小很多的时候,在内存中加载较小的下采样 Image 来解码较大图片,可以避免不必要的内存和 CPU 消耗。(WWDC 18 的Image and Graphics Best Practices

​接入方式

  • 新版本通过 UIImageView-Category / UIButton-Category 方式请求图片
[imageView setBd_isOpenDownsample: **YES** ];// 打开降采样开关,图片请求会传入 view 的 size
    [imageView bd_setImageWithURL:[NSURL URLWithString:url]options:BDImageRequestDefaultOptions];
  • 通过 Manager 方式请求图片
[[BDWebImage shareManager]requestImage:url
                                  options:options
                                       size:CGSizeMake(width, height)
                                   complete:complete];// 通过指定 size 限制图片采样大小

注意:

  1. Size == CGSizeZero 或者 view 在发起图片请求时 size 未知时,不会进行降采样

  2. 同时请求多个不同 size 的同一张图片,会解码并缓存多个 size 的图片

  1. ​预加载跳过解码(低端机)
  • BDWebImage 默认已经打开了预解码。在 prefetch 的时候会下载并解码图片,最后存到缓存中,这样可以提高图片的体验。但是,在内存有限的低端机中,有可能因为预加载太多图片,同时解码内存暴涨导致OOM。

  • 我们提供了一个开关,将所有的预加载都跳过解码阶段,避免了内存暴涨。

​接入方式

  • 建议:只在低端机上开启,因为跳过了解码阶段,解码会延迟到展示时进行
[BDWebImage shareManager].isPrefetchIgnoreImage= YES;


request.bizTag =@"feed";//在不同业务的请求设置一个标识业务的字符串,如“feed”、“detail”

[BDWebImageManager sharedManager].checkMimeType = NO;

[BDWebImageManager sharedManager].checkDataLength = NO;

BDWebImageRequest.isMonitorLargeImage = **YES** ;// 大图监控开关,默认关闭

BDWebImageRequest.largeImageFileSizeLimit =10*1024*1024;// 判断是否为大图的文件大小阈值,默认为20MB

BDWebImageRequest.largeImageMemoryLimit =1440*810*4;// 判断是否为大图的内存占用阈值,默认为 屏幕分辨率 * 4

[BDWebImageManager sharedManager].isCacheMonitorEnable = YES;// 缓存监控控制开关

[BDWebImageManager sharedManager].cacheMonitorInterval =120;// 缓存监控间隔时间,默认时 1 分钟采集一次

[imageView bd_setImageWithURL:[NSURL URLWithString:@"https://ws4.sinaimg.cn/large/006tKfTcly1fnl3r44e79g30am062qv8.gif"] options:BDImageAnimatedImageProgressiveDownload];

[BDWebImage shareManager].isPrefetchLowPriority = YES;

[imageView setBd_isOpenDownsample: **YES** ];// 打开降采样开关,图片请求会传入 view 的 size

[imageView bd_setImageWithURL:[NSURL URLWithString:url]options:BDImageRequestDefaultOptions];

[[BDWebImage shareManager]requestImage:url

                                options:options

                                   size:CGSizeMake(width, height)

                               complete:complete];// 通过指定 size 限制图片采样大小

[BDWebImage shareManager].isPrefetchIgnoreImage= YES;