前言
是什么
WebP的有损压缩算法是基于VP8视频格式的帧内编码,并以RIFF作为容器格式。因此,它是一个具有八位色彩深度和以1:2的比例进行色度子采样的亮度 - 色度模型(YCbCr 4:2:0)的基于块的转换方案。不含内容的情况下,RIFF容器要求只需20字节的开销,依然能保存额外的 元数据 (metadata)。WebP 图像的边长限制为16383像素。
在WebP的官网中,我们可以发现Google是这样宣传WebP的:
WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index.
简单来说,WebP图片格式的存在,让我们在WebP上展示的图片体积可以有较大幅度的缩小,也就带来了加载性能的提升。(摘自 https://nova.moe/re-introduce-webp-server)
怎么做
那么如何优雅的在不替换图片地址的情况下,将图片转为webp格式然后输出呢?
这时候就可以使用webp-sh组织最新开源的webp_server_go了,它的大概原理就是:当我们请求一张图片的时候使用web代理工具转发到webp_server_go应用进行处理,处理完成之后返回webp格式的图片,并且会保留处理后的图片以供后面的访问。
目前大部分主流浏览器都已经支持了webp图片的显示,除了Safari,但是不必担心,webp_server_go会自动判断请求来源是否为Safari,如果是,那么会返回原图。
Docker部署webps
官方Github:https://github.com/webp-sh/webp_server_go
Docker Hub:https://hub.docker.com/u/webpsh
本篇博客直接运行docker run命令,运行时检查系统中是否存在镜像,如果没有镜像,则直接去Docker Hub上拉取;如果有镜像,则直接运行。
#安装webps
docker run \
-d \
--name webps \
-p 3333:3333 \
-v /root/.halo:/opt/pics \
-v /root/.halo/cache:/opt/exhaust \
--network halonginx \
--restart=always \
webpsh/webps
-d 后台允许容器并将容器ID打印到控制台
--name 容器的名称
-p 容器的端口映射到主机
-v 绑定容器的卷,可以简单理解为将宿主机的目录指定到容器中,冒号左边是宿主机的目录,冒号右边是容器中的目录
--network 容器的网络【与halo保持一致】
服务成功启动后,查看docker容器
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b9c019b8a1e webpsh/webps "/usr/bin/webp-serve…" 55 minutes ago Up 10 minutes 0.0.0.0:3333->3333/tcp webps
进入webps容器
docker exec -it webps sh
确认/etc/config.json配置文件
vi /etc/config.json
{
"HOST": "0.0.0.0",
"PORT": "3333",
"QUALITY": "80",
"IMG_PATH": "/opt/pics",
"EXHAUST_PATH": "./exhaust",
"ALLOWED_TYPES": ["webp","jpg","png","jpeg","bmp"],
"ENABLE_AVIF": false
}
~
HOST 服务的主机名(IP),"0.0.0.0"表示所有,无特殊需求不需要修改
PORT 服务的端口号,默认即可,无特殊需求不需要修改
QUALITY 转换的的质量,默认80,根据实际需要修改
IMG_PATH 需要转换的文件存储目录,docker下默认存储到/opt/pics,无法修改,非docker请根据实际环境修改
EXHAUST_PATH 转换后的文件目录,docker下默认存储到/opt/pics,无法修改,非docker请根据实际环境修改
ALLOWED_TYPES 需要转换的文件格式
ENABLE_AVIF 是否开启转换成AVIF,默认关闭(false),暂不建议开启。
配置nginx代理
因为之前已经安装过nginx,直接修改default.conf,也预先准备好了二级域名,贴上nginx配置,具体配置参照上篇博客
server {
listen 80;
server_name findmyfun.xyz;
#return 301 https://$host$request_uri;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name findmyfun.xyz;
...
client_max_body_size 1024m;
location ^~ /upload/ {
proxy_pass http://webps:3333;
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header X-Powered-By;
proxy_set_header HOST $http_host;
expires 7d;
}
location / {
proxy_pass http://halo:8090;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
proxy_pass 设置代理服务器的协议和地址,以及位置应该映射到的URI。
proxy_set_header 允许重新定义或追加字段到传递给代理服务器的请求头。
proxy_hide_header 指定不会被传递的附加字段。默认情况下,nginx不会传递报头字段"Date"、"Server"、"X-Pad"和"X-Accel"从代理服务器到客户端的响应中。
expires 指定过期时间
结语
查看上图中的Type列,图片的返回格式已经变成了webp,而且图片大小已经远远降低,那么说明你的配置已经成功了。have fun!
如果用的开心,请关注一下官方GitHub项目哦!另外,他们还有其他语言的版本,请查看 https://github.com/webp-sh。
参考文献
1、优雅的让 Halo 支持 webp 图片输出
2、使用Docker安装WebP Server
3、让你的网站图片以WEBP格式输出
4、让站点图片加载速度更快——引入 WebP Server 无缝转换图片为 WebP
评论区