You need to enable JavaScript to run this app.
导航

使用移动端 SDK 实现图片渐进式加载

最近更新时间2023.12.15 11:05:58

首次发布时间2023.12.07 17:30:39

您可通过以下内容在双端 SDK 使用图片的渐进式加载能力,以减少用户浏览时的等待时间提升浏览体验。

使用场景

  • 图片体积较大:对于大型高分辨率的图片,完整加载可能需要较长时间。使用渐进式加载可以在图片加载过程中逐步显示内容,让用户更快地看到预览或模糊版本的图片。随着加载的进行,逐渐显示更多的细节和清晰度。

  • 弱网环境优化:在网络速度较慢或不稳定的情况下,完整加载大图可能会导致长时间的等待和卡顿。使用渐进式加载,可以先加载低分辨率或模糊版本的图片,使用户可以先看到部分内容,无需等待整个图片加载完成。

  • 内存紧张:在内存有限的设备上,加载大图可能会导致内存紧张和性能问题。使用渐进式加载,可以按需加载图片的不同阶段,避免一次性将完整图片加载到内存中。逐步加载可以减少内存占用,并提高应用程序的稳定性和响应性。

实现流程

说明

双端支持渐进式加载的图像格式分别为:

  • Android 端:awebp(动图)、jpeg(静图)、heic(静图)

  • iOS 端:gif(动图)、heif(动图)、awebp(动图)、heic(静图)、jpeg(静图)、png(静图)

收益参考

说明

缩略倍数指在原图基础上编码缩小一定倍数的小分辨率图片,可指定缩小分辨率倍数在 5~10 之间。默认配置为 5。

以下为选择了大约 20KB 左右大小的文件并在本地测试后,得出的 HEIC 缩略图的倍数与体积增加的关系说明。

原图宽高的范围缩略为 5 倍时缩略图体积增加的百分比缩略为 8 倍时缩略图体积增加的百分比缩略为 10 倍时缩略图体积增加的百分比

宽:(500,1280)
高:(500,720)

10.46%

5.78%

4.48%

宽:[1280,1920]
高:[720,1080]

12.29%

6.55%

4.86%

宽大于 1920;高大于10809.71%4.84%3.46%
平均值10.81%5.70%4.24%

上述数据表明,相同类型的原图随着缩略倍数的增加,其 HEIF 缩略图的体积增加百分比也会相应减小。缩略图主要收益来源于网络数据接收+解码耗时,预计在客户端从收到首字节到接收完整图片数据的过程中,可实现 95 分位可感知耗时减少 120 ms 的收益。为了达到这个目标,首先需要考虑文件大小对耗时的影响。您可以根据上表中的数据,结合您的业务需求和网络环境,选择适当的文件大小和缩略倍数。

注意事项

  • 您需要使用 veImageX 官方解码库或者双端 SDK 开启 heic 渐进式加载,系统解码无法支持。
  • 在 Android 端使用 heic 渐进式加载前,请确保已参考 HEIF 加载配置优先使用软解能力,即指定HeifFormatDecoderfalse。iOS 端默认优先使用软解,您无需手动配置。
  • 为了保障您的渐进式加载效果,推荐您接入最新版 SDK
  • 如需验证渐进式效果,请参考各接入中的渐进式效果验证说明配置忽略查找内存缓存,确保每次的下载均为渐进式网络下载。

加载类型

分块加载

分块加载将资源(静图或动图)分成多个块或片段,通过按需加载和显示这些块或片段来使用户可以迅速获取部分内容,并逐步呈现更多的细节和完整内容,以减少等待时间和加载延迟。

如动图边下边播、从上到下的渐进式显示(iOS 端,仅 jpeg 和 png)。效果图如下所示:

动图会在下载过程中逐步显示,用户可以在动图加载的同时观看已下载的部分内容,而不需要等待整个动图完全下载。这种方式可以提高用户体验,使用户更快地开始观看动图,并在加载过程中逐步显示更多的帧。

正常网络下,首帧加载速度会快很多,播放过程基本不会出现卡顿;弱网状态下,边下载边播放,若下一帧还未下载好则暂停,如视频所示,最终全部下载完后正常播放。

分层加载

分层加载通过将内容分成多个层次或优先级,并按需加载和显示这些层次,即从模糊到清晰的渐进式显示效果。该方式可让用户在加载过程中快速获取基本信息,并逐步呈现更多的细节和内容,从而减少等待时间并提升交互体验。

如 heic 静图开启渐进式后,会优先加载缩略图,缩略图数据传输完毕便可先进行解码显示出来,等原图下载完毕后再显示原图,整体效果就是从模糊到清晰。(若图片数据中检测不到缩略图信息,则开启渐进式加载无效)。效果图如下所示:

操作准备

在双端开启 heic 静图渐进式加载或在 Android 端开启 jpeg 静图渐进式加载时,您需要参考以下内容在 veImageX 控制台的图片模板中开启相应渐进式加载配置。

  1. 登录 veImageX 控制台,进入图片处理配置页面。

  2. 单击新建模板按钮,完成以下配置:

    1. 指定输出格式为 heic

    2. 开启缩略图并指定缩略图相较于原图的倍数

    3. 按需配置其他图片处理能力

    alt

开启 iOS 端渐进式加载

流程说明

iOS 端框架 BDWebImage 对渐进式图片的加载步骤如下所示:

渐进式下载

使用分块传输方式,逐步获取图像数据(image data)。表示图像数据被分成多个块或片段,按需下载和接收。

渐进式解码

  1. 首次解码:解析 data 信息、首帧图像数据,解码出动图对象 BDImage,附带渐进式标识 bd_loading(是否正在下载)。
  2. 后续解码:更新对应 BDImage 的 data。

因为是同时在更新 BDImage 的 data 和 使用 data 解码,需要进行加锁。

渐进式播放

  1. 正在下载中,播放到当前最后一帧暂停。
  2. BDImage 的 data 更新,继续播放到当前最后一帧。
  3. 下载完成,正常循环播放。

具体接入

请参考集成准备快速开始接入并初始化最新版 iOS 加载 SDK ,并参考以下内容开启各类型图片的渐进式加载。

动图渐进式加载

您可参考以下代码示例填写待加载的 gif/heif/awebp 格式动图地址,实现动图边下边播。

请在实际业务中使用以下代码示例,实现 gif/heif/awebp 图片的渐进式加载。
NSURL *url = [NSURL URLWithString:@"https://xxx.xxx"]; 
[imageView bd_setImageWithURL:url options:BDImageAnimatedImageProgressiveDownload];
  

静图渐进式加载

根据加载格式的不同,静图渐进式加载分为从上到下的渐进式显示(分块加载)和从模糊到清晰的渐进式显示(分层加载)。

  • 从上到下的渐进式加载

参考以下代码示例填写待加载的 jpeg/png 格式图片地址,实现从上到下的渐进式加载。

请在实际业务中使用以下代码示例,实现 jpeg/png 图片的渐进式加载。
NSURL *url = [NSURL URLWithString:@"https://xxx.xxx"];
[imageView bd_setImageWithURL:url options:BDImageStaticImageProgressiveDownload];
  
  • 从模糊到清晰的渐进式加载

注意

对于 heic 渐进式加载,请确保已完成控制台模板的渐进式加载配置

  1. 简单加载

参考以下代码示例填写待加载的 heic 格式图片地址,实现从模糊到清晰的渐进式加载。

请在实际业务中使用以下代码示例,实现 heic 图片的渐进式加载。
NSURL *url = [NSURL URLWithString:@"https://xxx.xxx"];
[imageView bd_setImageWithURL:url options:BDImageHeicProgressDownloadForThumbnail];
  
  1. 自定义渐进时长

设置transitionDuration即缩略图和全尺寸图像的过渡动画的持续时间,单位为秒。较长的持续时间可以产生更流畅的过渡效果,您可自定义参数以实现不同加载效果。

请在实际业务中使用以下代码示例,实现 heic 图片的渐进式加载。
NSURL *url = [NSURL URLWithString:@"https://xxx.xxx"];
[BDWebImageRequestConfig *config = [BDWebImageRequestConfig new];
config.transitionDuration = 2.5;        // 设置 transition duration,值越大越可以更清晰地看到缩略图到大图的渐变效果
[imageView bd_setImageWithURL:url options:BDImageHeicProgressDownloadForThumbnail | BDImageRequestSetAnimationFade];
  
  1. 自定义是否获取缩略图

您可选择是否将 heic 格式缩略图通过回调下发到业务 APP。由于 heic 静图渐进式加载会前后加载两张图片(缩略图和原图),您可以通过如下方式对缩略图也进行一次图片加载完成的回调,将缩略图也抛回给业务层。

请在实际业务中使用以下代码示例,实现 heic 图片的渐进式加载。
NSURL *url = [NSURL URLWithString:@"https://xxx.xxx"];
[imageView bd_setImageWithURL:url options:options:BDImageHeicProgressDownloadForThumbnail | BDImageHeicThumbnailPassToBusinessLayer];
  

说明

您可以通过设置BDWebImageRequest.minNotifiProgressInterval来控制解码的时机,即解码频率。取值范围是 [0,1],默认为0.05,即每下载5%的数据便尝试一次解码,如果设置过小会导致回调过于频繁从而影响性能。

开启 Android 端渐进式加载

流程说明

  1. 循环读取网络流,开启渐进式配置后,每100ms 处理一次目前读取的数据;

  2. 解析流的数据,数据足够更新图片时,调度下一次解码;
  3. Decoder 解码得到 Bitmap,然后生成 Drawable,给到 View 做展示。

说明

  • 对于 jpeg 静图:会从清晰度低的图片逐渐显示到清晰度高的图片,则数据足够更新图片代表扫描到了更加清晰的结果。
  • 对于 heic 静图:会先加载缩略图,待到原图加载完毕再显示原图,所以相当于加载两张图片。
  • 对于 webp 动图:播放到当前已有最后一帧,全部加载完毕后正常播放,所以上述数据足够更新图片代表有新的一帧图像的数据。

具体接入

请参考集成准备快速开始接入并初始化最新版 Android 端 BDFresco 加载 SDK ,并参考以下内容开启渐进式加载。

动图渐进式加载

您可参考以下代码示例填写待加载的 awebp 格式动图地址,实现动图边下边播。

  1. 全局开启

参考以下代码示例,实现在应用范围内使用 Fresco 库加载的图像请求都会自动开启渐进式加载。

说明

全局开启渐进式加载时不支持配置忽略查找内存缓存,建议在单个 URL 请求验证渐进式加载效果。

ImagePipelineConfig.getDefaultImageRequestConfig().setProgressiveRenderingAnimatedEnabled(true);
  1. 单个请求开启

参考以下代码示例,实现针对特定的请求开启渐进式加载。

请在实际业务中使用以下代码示例,实现 awebp 图片的渐进式加载。
mSimpleDraweeView = findViewById(R.id.my_image_view);
ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(Uri.parse("url"));
builder.setProgressiveRenderingAnimatedEnabled(true);
DraweeController controller = Fresco.newDraweeControllerBuilder()
        .setAutoPlayAnimations(true)
        .setImageRequest(builder.build())
        .setOldController(getController())
        .build();
mSimpleDraweeView.setController(controller);
  

静图渐进式加载

说明

  • 在使用 jpeg 和 heic 的渐进式加载前,请确保已完成控制台的模板配置
  • 使用 heic 渐进式加载前,请确保已参考 HEIF 加载配置优先使用软解能力,即指定HeifFormatDecoderfalse
  • jpeg 渐进式加载

参考以下代码示例填写待加载的 jpeg 格式图片地址,实现从模糊到清晰的渐进式显示。

  1. 全局开启

参考以下代码示例,实现在应用范围内使用 Fresco 库加载的图像请求都会自动开启渐进式加载。

说明

全局开启渐进式加载时不支持配置忽略查找内存缓存,建议在单个 URL 请求验证渐进式加载效果。

ImagePipelineConfig.getDefaultImageRequestConfig().isProgressiveRenderingEnabled() = true;
  1. 单个请求开启

参考以下代码示例,实现针对特定的请求开启渐进式加载。

请在实际业务中使用以下代码示例,实现 jpeg 图片的渐进式加载。
mSimpleDraweeView = findViewById(R.id.my_image_view);
ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(Uri.parse("url"));
builder.setProgressiveRenderingEnabled(true);
DraweeController controller = Fresco.newDraweeControllerBuilder()
        .setOldController(mSimpleDraweeView.getController())
        .setAutoPlayAnimations(true)
        .setImageRequest(builder.build())
        .build();
mSimpleDraweeView.setController(controller);
  
  • heic 渐进式加载

参考以下代码示例填写待加载的 heic 格式图片地址,实现从模糊到清晰的渐进式显示。

  1. 全局开启

参考以下代码示例,实现在应用范围内使用 Fresco 库加载的图像请求都会自动开启渐进式加载。

说明

全局开启渐进式加载时不支持配置忽略查找内存缓存,建议在单个 URL 请求验证渐进式加载效果。

ImagePipelineConfig.getDefaultImageRequestConfig().isProgressiveRenderingHeicEnabled() = true;
  1. 单个请求开启

参考以下代码示例,实现针对特定的请求开启渐进式加载。

请在实际业务中使用以下代码示例,实现 heic 图片的渐进式加载。
mSimpleDraweeView = findViewById(R.id.my_image_view);
ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(Uri.parse("url"));
builder.setProgressiveRenderingHeicEnabled(true);
DraweeController controller = Fresco.newDraweeControllerBuilder()
        .setOldController(mSimpleDraweeView.getController())
        .setAutoPlayAnimations(true)
        .setImageRequest(builder.build())
        .build();
mSimpleDraweeView.setController(controller);