好长时间没有关注WebP的支持性了,乍一看欸好像连QQ浏览器都能完美支持WebP了。很早之前就有关注WebP-Server这一过渡工具,恰好最近糖哥送了博主一台腾讯云无忧轻量,在国内的轻量上部署一番,感受一下WebP带来的提升。
一、概述
WebP是由Google开发的一种高效的图片压缩方案(Google WebP),相比无损的png
一般情况下WebP 20%有损压缩能够达到最高75%的压缩比例。也正如Google宣传的那样,WebP 的压缩率通常比 JPEG 和 JPEG 2000 平均高出 30%,而又不会降低图片质量。
但是直至2023年,纯WebP存储依然面临着很大的历史遗留问题。访问方面问题相对比较小,仅是iOS 14以前的Safari并不支持,国内外主流的现代浏览器都已经悉数支持了WebP图片的加载(支持性统计)。但是各类生产力工具,比如Ps、Ai等依然不支持加载WebP图像,如果原始图片仅保留WebP的话意味着放弃了一小部分旧设备加上失去了编辑的便利性。一边是WebP带来极致的媒体加载体验,一边是失去部分编辑的便利性,博主之前常常纠结于这些取舍,碍于不能完美解决问题而对新技术望而却步。
前一段时间,偶然的机会我的群友提到了WebP-Server这个过渡工具。这是一个基于go语言的WebP转换中间件,与很多CDN提供的过渡策略一样,能够在使用原图储存的基础上,通过访客UA判断浏览器支持性决定返回WebP或原图。相应的,WebP-Server也能够支持生成WebP缓存,以及像CDN一样作为边缘访问节点实现对源站请求的压缩。
项目主页:https://webp.sh
项目文档:https://docs.webp.sh/usage/basic-usage
GitHub:https://github.com/webp-sh/webp_server_go
纵观我们国内的服务器市场,在个人经济能力能够承受范围的带宽最大也就4-5M。基于这样的假设,我们可以理论计算一下,5M的带宽大约能为你提供640k/s的传出能力,以博主的经验平均8张图/页面、100k/图,单个PV下就要占满带宽1.25秒完成图片的加载。但是在20%有损WebP压缩的情况下,图片平均大小降至16-25k,能够使1秒内PV并发能力提高5倍,这在服务器带宽非常捉襟见肘的国内网络环境下对站点的负载能力提升是立竿见影的。也是基于这个现状,如果自用的图床能够配置WebP,很可能就不必再为CDN额外付费,仅通过高质量的BGP网络完成服务的提供。
在疫情后降本增效的大环境下,也只有腾讯云4月上云精选(点击前往)依然在提供三年408 2C/2G/4M和628 2C/4G/5M的轻量应用服务器了。最近糖哥送了我一台腾讯云的无忧轻量,1C/2G/5M的配置与活动款带宽基本一致。题外话,最近腾讯云开放了无忧的付费升配通道,持有无忧的小伙伴在有需要的情况下可以按需选择升级到更高的配置。
二、WebP Server
由于WebP-Server需要libaom组件,并且需要libc6>2.34,博主建议使用CentOS 8 / Debian 11及以上的系统。尽管较早的系统可以通过编译来对libc6版本进行升级,但这是一个十分危险的操作,很可能会导致系统关键组件出现问题。因此对于较早的系统,博主更加推荐直接使用docker进行部署(官方文档),支持ARMv7(32bit)、ARM64(Aarch64)和AMD64(x86-64),可以在DockerHub上查看(点击前往)。
1 2 |
# 【/path/to/pics】指的是图片路径,【/opt/pics】指的是生成的WebP缓存路径 docker run -d -p 3333:3333 -v /path/to/pics:/opt/pics --name webp-server webpsh/webp-server-go |
手动安装的话,必要的组件就是libaom3
,这个组件略微有点坑,预编译包会默认读取libaom.so.3
这个.so
,安装好之后如果还是提示找不到libaom3
,可以试试通过ln -s
做一个软连接。
1 2 3 4 5 6 7 |
# 安装libaom库 apt install libaom-dev yum install libaom-devel # 在RHEL系(CentOS)中解决找不到依赖的问题 ln -s /usr/lib64/libaom.so.0 /usr/lib64/libaom.so.3 #在Debian系中解决找不到依赖的问题 ln -s /usr/lib/x86_64-linux-gnu/libaom.so.0 /usr/lib64/libaom.so.3 |
预编译包可以从GitHub下载(点击前往),配置文件请按你的实际需要选择模式并修改参数,以下各项参数的解释已写在注释里面,修改完成后可以保存为config.json
文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#代理模式 { "HOST": "127.0.0.1", //监听本地主机,使用0.0.0.0可监听全部 "PORT": "3333", //WebP Server使用的本地端口 "QUALITY": "80", //压缩质量,越低图片压缩比越高 "IMG_PATH": "https://test.webp.sh", //反代的站点 "EXHAUST_PATH": "/path/to/exhaus", //缓存WebP的保存路径 "ALLOWED_TYPES": ["jpg","png","jpeg","bmp","gif"], //压缩的后缀类型 } #本地模式 { "HOST": "127.0.0.1", //监听本地主机,使用0.0.0.0可监听全部 "PORT": "3333", //WebP Server使用的本地端口 "QUALITY": "80", //压缩质量,越低图片压缩比越高 "IMG_PATH": "/path/to/pics", //本地图片路径,一般设置为站点根目录 "EXHAUST_PATH": "/path/to/exhaust", //缓存WebP的保存路径 "ALLOWED_TYPES": ["jpg","png","jpeg","bmp","gif"], //压缩的后缀类型 "ENABLE_AVIF": false //av1压缩支持,暂不建议使用 } |
直接安装的话建议使用systemd启动服务,以下是一个一键写入webp.service
的示例,修改好webp-server
二进制文件和config.json
文件的路径,直接粘贴进ssh窗口即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
cat > /etc/systemd/system/webp.service <<EOF [Unit] Description=WebP Server Documentation=https://github.com/n0vad3v/webp_server_go After=nginx.target [Service] Type=simple StandardError=journal AmbientCapabilities=CAP_NET_BIND_SERVICE WorkingDirectory=/[程序目录]/webp-server ExecStart=/[程序目录]/webp-server/webp-server-linux-amd64 --config /[程序目录]/webp-server/config.json ExecReload=/bin/kill -HUP $MAINPID Restart=always RestartSec=3s [Install] WantedBy=multi-user.target EOF |
至此,你就可以使用service webp start|stop|status
来控制WebP Server的运行了,确认无误后使用systemctl enable webp
来允许其开机启动。
三、NGINX设置
在WebP-Server工作正常之后,我们需要在NGINX上配置一个反向代理,将jpg|jpeg|gif|png|bmp
这些后缀的媒体文件交给WebP-Server来处理。以下是一个示例,加在NGINX对应的vhost中即可。需要注意的是,开启了WebP自动返回之后,同时需要在vhost中删除掉NGINX对相关媒体后缀的缓存内容,以免将WebP返回给了不支持的设备。
1 2 3 4 5 6 7 8 |
# 将jpg|jpeg|gif|png|bmp请求转发至本地3333端口 location ~* \.(?:jpg|jpeg|gif|png|bmp)$ { proxy_pass http://127.0.0.1:3333; proxy_set_header X-Real-IP $remote_addr; proxy_hide_header X-Powered-By; proxy_set_header HOST $http_host; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; } |
四、补充&总结
在撰写文章的过程中,有朋友提醒说目前该程序存在内存泄漏的情况(点击前往),作者建议使用Docker通过限制内存使用来避免这个问题。这个问题是在多人同时访问单个媒体资源时WebP Server会对同个文件启动多个压缩进程,进而导致异常的内存占用。如果直接安装同时为了更好的体验,缓存预热是一个非常明智的选择。
1 2 |
# 启用4进程对配置目录进行缓存预热 ./webp-server -prefetch -jobs=4 --config /[程序目录]/webp-server/config.json |
作者在GitHub上的预编译包仅提供了64位x86
的架构,博主感觉作者是在RHEL8
系上构建的预编译包,如果想在其他平台使用可以考虑使用docker或者按照文档(点击前往)进行编译,整个流程并不复杂。配置好后打开F12 Network选项卡,勾选类型选项或者在图片的content-type可以看到,我们实际访问的图片已经被压缩成了webp
。
最后,还是再次感谢作者写出这样一个好用的小工具吧~
*半原创文章,转载无需注明出处
我使用的是腾讯云cdn,腾讯云现在可以添加webp选项了呢,打开开关就好了,每月大概几块钱
(~ ̄▽ ̄)~
0IP博客就没考虑过兼容性。
因为开始写博客用的是虚机,
从一开始就直接全上了WebP。
webp,不是系统默认支持的格式。始终有隔阂。
你好,请问一下,通过
ln -s /usr/lib/x86_64-linux-gnu/libaom.so.0 /usr/lib64/libaom.so.3
建立软连接后仍然报错怎么办呀…还是报错:./webp-server-linux-amd64: error while loading shared libraries: libaom.so.3: cannot open shared object file: No such file or directory
libaom.so
是位于哪个文件夹中,如果在左侧的路径的话试试再ln -s
一份到/usr/lib/libaom.so.3
最近刚好也有在研究这个;不过感觉作为个人站点来说,CDN 缓存命中率也是很重要的一部分,如果图片多 serve 一个版本反而会降低命中率,而且 CDN 在那种情况下又要直接回源(因为要返回访客 UA 作判断)而不能用缓存。
最佳的方案应该是 CloudFlare Image / 又拍云集成 / 腾讯万象优图(是叫这个吧?)从 CDN 节点做 webp 优化。
目前作为 low cost(实际上是 0 cost)方案我直接用了 WordPress 的 Photon(i0.wp.com),反正国内的 CDN 无论如何无法防刷()
不过博主看起来是国内单点,那作用还是有的。可惜我的域名没备案,.dev 也无法备案。