阿里云OSS使用的一些问题记录

01-26, 2022

公司 APP 中的图片资源是存储在阿里云 OSS 中,由于图片资源在上传端没有做限制,导致 OSS 里存储的图的巨大,影响了 C 端页面的渲染速度。虽然项目中也有使用到 OSS 提供的缩放功能,但是仍有一些地方需要优化,以下就是记录我优化的方向:

统一的 url 处理入口

原先的的做法是提供一个工具函数将原图片地址转换成一个含剪切 queryString 的地址,这种做法的缺点是无法每个使用的地方都需要额外的调用一次这个函数,伪代码是:const compressedUrl = getCompressedUrl(originUrl, size)。仔细思考一下就会发现 originUrl 和 size 这两个数据我们其实还会传递给我们的 Image 组件,我们完全可以将 url 处理过程内置到 Image 组件中即可。所以最终的做法是将这个调用转换工具函数的逻辑内置到一个自定义图片组件中,通过读取图片的 source 和 style 即可获取到我们需要的 originUrl 和 size,转换后的 url 也是在我们自定义图片组件内部进行消费。这样,整个处理过程对业务方是无感知的。

缩放模式的选择

我们使用缩放的场景的前提是我们必须至少知道图片宽高中的一项。但实际使用中,只设定目标宽/高和同时设定宽高是会受缩放的 mode 影响的。在我们公司的项目中,默认的缩放 mode 是 fill,即缩放到目标尺寸,对超出部分进行裁切。但是如果我们只指定了宽/高,那么在该模式下会按宽高比 1:1 来裁剪,但是通常情况下我们只指定宽/高通常其它的是保持等比缩放。这种情况下我们就需要使用另外一种 mode,即 OSS 默认的 lfit/mfit,这时图片才会保持宽高等比缩放。所以在我们的处理函数中还应该根据传入的设定目标是否同时包含宽高来选择缩放的 mode。

quality 未生效

查阅文档后发现 OSS 的 quality 是只针对 jpg、webp 格式,而公司的大部分图片都是 png 格式的。

追求更小的尺寸

OSS 还支持 format 处理,我们可以将原图转换到 webp 格式,这样压缩后的图片尺寸能减少 30%(压缩率因图片而异),但是需要注意的是 webp 还有兼容性,我们需要做兼容处理。APP 中是通过 JavaScript 根据当前系统版本来选择是否启用格式转换。如果是在 HTML 中可以使用 picture 标签来做兼容处理。

示例代码如下,source 用于声明针对特定 MIME 类型的资源地址,注意它只是资源的声明,并不是实际的图片元素,即使在浏览器支持 webp 的情况下,我们的 webp 图片实际仍然是渲染在 img 标签上,而 img 标签默认的资源将不生效。所以我们对图片的样式或者其它属性的声明都应该在 img 标签上。

<picture>
  <source srcset="xxx.png?x-oss-process=image%2F%2Fformat%2Cwebp" type="image/webp">
  <img src="xxx.png" />
</picture>