手淘图片库新特性解析( 二 )


手淘图片库新特性解析文章插图

  1. Init:初始化图片解码器 , 并将相应的数据结构透传到UC
  2. Decode:UC会透传相应的数据到解码器 , 解码器解码完成后将相应的RGBA数据给到UC , UC最终将解码后的数据给到渲染层
  3. Close:回收初始化过程中创建的系统资源
之前从事过PC开发的同学可能会熟悉这这种做法 , PC插件化大多是利用dll(可以理解为Linux下的so)来实现 , 这在PC时代是常用做法 , Python调用C++/C代码也可以通过封装为so进行调用 。 针对UC提供的这种能力 , 图片库对原有的HEIC解码器做了封装 , 实现了上面的接口规范 , 提供给UC调用 , 这样H5解码HEIC的问题就解决掉了 。
真的这么顺利么?答案是No 。 手淘目前对so集成时的大小有限制 , 刚好HEIC的32位和64位so加起来将近4.5MB , 这已经是严重超标了 , 是不可以接受的 。
那该如何解决呢?架构组提供了远程加载so组件(上图中的远程下载) , 可以将so放在远程 , 不需要打进apk包 , 当需要的时候从远程下载 , 同时HEIC解码so是独立的没有依赖 , 直接dlopen打开就可以使用 。 这样我们的解码功能就顺利完成了 , 剩下的工作就需要Windvane同学添加相应的降级逻辑和监控逻辑提供必要的稳定性保障 , 到这里这个H5支持HEIC功能就完成了 。
说了这么多从native支持HEIC到H5支持HEIC , 收益是什么呢?有两个方面 , 一个是端上的收益 , 一个是服务端收益:
客户端
目前端上的计算能力已不是瓶颈 , 主要是网络的通信时间 , 图片体积越小 , 网络耗时越少 , 同时网络耗时的减少可以抵消端上解码耗时的增加 , 总体而言图片的加载性能会提高 。 同理对于H5页面也一样 , 网络耗时越少 , 页面性能也会有所提高 。
服务端
对于服务端而言 , 图片的体积更小 , 占用的带宽也更小 , 单位时间内处理的请求增加 , 简单来说就是提高了QPS 。
H5支持HEIC这个功能已经灰度了几个版本 , 后续会逐步全量 , 对于H5页而而言 , 页面性能也会得到提升 。
我们可以先参考下native页面下HEIC图片和WEBP图片的下载时间和解码时间的对比数据:
Format
网络时间(ms)
解码时间(msHE)
HEIC
141
27.5
WEBP
645
30
手淘图片库新特性解析文章插图
数据说明:样本数在几十万级别 , 基本可以抹平图片尺寸带来的统计差异 。
从上面的数据也可以表明 , 网络时间的优化可以抵消部分解码时间的增加 , 有的同学看到数据会有疑问 , 解码时间并没有增加反而有所优化 , 这主要是多媒体算法团队对HEIC解码做了优化 , 同时图片空间空间同学对HEIC的封装做了优化(优化的后的封装 , 仍然是符合HEIF文件标准的) 。
图片库缓存标准化
? 图片库磁盘缓存标准化
用过Phenix图片库或者三方开源图片库的同学都知道 , 图片库会有三层缓存(内存、磁盘、网络) , 磁盘缓存一般是持久化的 , 除非超过磁盘缓存大小被LRU淘汰掉 , 为了满足图片空间的需求 , 图片库对磁盘缓存做了改造 。 大体流程如下:
手淘图片库新特性解析文章插图
简单来说图片库的磁盘缓存可以指定过期时间 , 过期后图片请求会打到后端 。 图片空间会在图片响应头里添加过期字段来控制本次请求到的图片在磁盘缓存中存在的时长 。 目前实现的缓存控制是在原先LRU基础上实现的 , 即首先会判断这张图片有没有被LRU淘汰掉 , 如果没有被淘汰掉会走到缓存控制逻辑 , 如果已经被LRU淘汰 , 保持原有逻辑 。