搭建资源代理服务来优化 HTTP 图片资源

155 阅读3分钟

前言

图片类的资源引用是前端开发中最常见的功能,一般直接使用资源 URL 引用原文件。

一些第三方对象存储平台提供引用资源时的处理参数,比如“七牛云”可以在引用图片时做一些缩放、裁剪等操作,给客户端提供了灵活性,同时也可以优化图片加载速度,节省服务器带宽流量。

新项目可以考虑直接使用第三方存储平台来优化资源。老项目迁移成本较高,动辄上 TB/PB 的资源迁移是一个巨大的难题,况且还有各个地方的引用地址需要更新,这样的迁移成本令人望而却步。

代理

既然不能迁移,那我们就使用代理来优化图片资源。

原来的图片加载流程:

客户端 -> 图片服务器 -> 客户端拿到图片

代理流程:

客户端 -> 代理服务器 -> 图片服务器 -> 代理服务器拿到图片并处理 -> 客户端拿到图片

GraphicsMagick

GraphicsMagick 是图片处理中的瑞士军刀。它提供了一个强大高效的图片处理工具集,包括读取、写入、操作超过 89 种主流格式的图片,例如:DPX, GIF, JPEG, JPEG-2000, PNG, PDF, PNM, TIFF, WebP。

gm 是封装调用 GraphicsMagick 的 Node.js 库。

源码

Github: li-yechao/gm

Docker Image: github.com/li-yechao/g…

运行

使用 docker 运行 gm-server

docker run --rm -it \
  -v /static-file-path:/app/static \
  -p 8080:8080 \
  ghcr.io/li-yechao/gm-server

也可以自定义 env 配置文件

port=8080
cors=false

static.rootDir=./static

注意env 文件需要挂载到容器中的 /app/.env 路径

docker run \
  ... \
  -v /env-file-path:/app/.env \
  ...

API

请求路径:/proxy

查询参数:

  • src [required, type: string] 原始图片 URL

  • autoOrient [optional, type: 1] 自动去除 Orientation 信息,避免某些低级设备显示图片旋转,例如:autoOrient=1

  • width [optional, type: number] 图片宽度

  • resizeMode [optional, type: %|<|>]

    • %width 作为百分比进行缩放

    • < 仅在图片大小小于 width 的时候缩·放

    • > 仅在图片大小大于 width 的时候缩放

  • quality [optional, type: 1 - 100] 图片质量

  • format [optional, type: string] 图片格式,例如 png, jpg, webp 等等

  • webp [optional, type: 1] 在验证客户端支持 webp 的情况下返回 webp 格式的图片,该参数优先级低于 format

使用:推荐使用下面的参数来优化图片资源,并且推荐把 src 参数放到最后面,避免参数识别错误的问题。

/proxy?autoOrient=1&webp=1&quality=70&width=750&resizeMode=>&src=...

效果对比

原图

URL: gm.yechao.xyz/proxy?src=h…

文件大小: 417KB

优化后

URL: gm.yechao.xyz/proxy?autoO…

文件大小: 11KB (Chrome 浏览器,支持 webp), 108KB (Safari without webp support)

小结

图片资源的优化是一个非常值得做的功能,不仅能提高响应速度,还能节省大量的带宽。特别是用户上传的图片,用户手机拍照上传一般都在 1MB 以上,有些甚至在 10MB 以上,然而优化后的图片一般在 100KB 以内,且用户几乎分辨不出原图和优化后图片之间的区别。