图片SDK我们在历史和对接过程和使用过程中总结了最佳使用实践,供参考使用;
图片的下载耗时主要在 建立连接 和 下载 两个阶段,可以通过连接复用优化建立连接的耗时、使用webp、heif、heic等图片格式来减小文件大小优化下载耗时
通过 网络优化开启 http2 + https,虽然 https 建立连接的耗时较长,但可以通过收敛业务的图片域名,提高链接的复用率,同时 http2 可以提高图片下载速度,最终对图片的加载速度是有一定优化的。
我们在不同业务做过实验,若连接复用率上达到了95%+,则其他各项指标也都比较靠前,解码失败率基本为0%,具备一定的抗劫持能力。
静图 webp、heif 格式、动图awebp 能够压缩更小的图片体积,虽然复杂的图片格式可能带来解码耗时微弱增加,但与下载耗时的优化相比,总的图片加载耗时大大缩短。
实验数据显示最终加载耗时对比:静图:heic < webp < jpeg < png 动图:heif< awebp < gif
最佳方案是先接入统计能力中的业务标示 biz_tag,通过这种方式,可以知道 app 中的格式分布、业务方的格式分布,从而去推动格式改造,事半功倍。
request.bizTag = @"feed"; //在不同业务的请求设置一个标识业务的字符串,如“feed”、“detail,通过这种设置可以在数据统计指标中看到不同指标的拆分信息;
因为默认jpg
等图片是从上到下显示的方式来渐进式加载,用户体验并不佳;而动图可以快速显示首帧,大大提升了用户体验。如果动图也采用webp
格式,与gif
相比,将节省30%的带宽。
BDImageAnimatedImageProgressiveDownload
选项[imageView bd_setImageWithURL:[NSURL URLWithString:@"https://ws4.sinaimg.cn/large/006tKfTcly1fnl3r44e79g30am062qv8.gif"] options:BDImageAnimatedImageProgressiveDownload];
使用BDImageRequestDefaultPriority
、BDImageRequestLowPriority
、BDImageRequestHighPriority
来控制下载请求的优先级。
现在已经提供了一个开关并且默认打开,将所有的预加载请求优先级设置为BDImageRequestLowPriority
[BDWebImage shareManager].isPrefetchLowPriority = YES;
图片有各种分辨率和大小。在很多情况下,它们的大小超过了 app 的要求。例如,一张 200 * 200 的图片加载到一个 100 * 100 的 ImageView 上,不会带来任何明显的好处,不仅会占用宝贵的内存,而且会因为额外的动态缩放而产生额外的性能开销。
当 View 的宽高比图片的宽高小很多的时候,在内存中加载较小的下采样 Image 来解码较大图片,可以避免不必要的内存和 CPU 消耗。(WWDC 18 的Image and Graphics Best Practices)
[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 限制图片采样大小
注意:
Size == CGSizeZero 或者 view 在发起图片请求时 size 未知时,不会进行降采样
同时请求多个不同 size 的同一张图片,会解码并缓存多个 size 的图片
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;