独立站图片WebP自动转换,Nginx实现图片格式自适应输出
图片加载速度直接决定独立站的首屏体验和转化率。
WebP 格式体积比 JPG 小 25%-34%,画质却几乎看不出差别。
本文要解决的问题是:利用 Nginx 的 map 和 try_files 两个指令,实现图片格式自适应输出——浏览器支持 WebP 就自动返回 .webp 文件,不支持就返回原 JPG/PNG,全程不需要改动页面里的图片地址。
这套方案不依赖第三方插件,也不要求你改数据库,适合 WordPress、自建商城以及任意静态站点。
你只需要能编辑 Nginx 配置文件,并且有一台可以执行命令的服务器。
配置前的准备:两个文件、一个模块
开始之前,先确认三件事:
- Nginx 版本不低于 1.10,太老的版本可能没有 map 指令。执行
nginx -v即可查看。 - 已经准备好图片目录,比如
/www/wwwroot/example.com/wp-content/uploads/,下文会基于这个路径举例。 - 服务器上安装了 cwebp 工具,用于把 JPG/PNG 批量转换成 WebP。未安装的话,在 CentOS 上执行
yum install libwebp-tools,在 Ubuntu 上执行apt install webp。
理解这套配置的核心逻辑,只需记住两句话:
map读取浏览器请求头里的Accept字段,判断对方是否支持 WebP。try_files按顺序查找文件,先找.webp后缀文件,找不到就回退到原图。
在 Nginx 里配置图片格式自适应输出
第一步:定义 map 变量(写在 http 块里)
打开 Nginx 主配置文件 /etc/nginx/nginx.conf,在 http {} 块内加入:
http {
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
# 其他配置……
}
这段配置的含义是:当请求头 Accept 包含 webp 字符时,$webp_suffix 变量的值变成 .webp,否则为空字符串。
第二步:在 server 块里修改图片请求规则
打开站点配置文件,在 server {} 内加入:
location ~* \.(png|jpe?g)$ {
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
}
以 https://example.com/wp-content/uploads/photo.jpg 为例,当浏览器支持 WebP 时,Nginx 会先去查找 photo.jpg.webp,查到了就直接返回;
查不到再返回 photo.jpg。
不支持 WebP 的浏览器则始终返回原图。
宝塔面板用户可直接在站点设置 → 配置文件里完成上述两步。
把 map 配置放到 http {} 段,把 location 配置放到 server {} 段,保存后执行 nginx -t 检查语法,再点“重载配置”即可。
给图片自动生成 WebP 文件
Nginx 本身不会帮你把 JPG 转成 WebP,所以需要先批量生成 .webp 文件。
下面这段脚本可以处理 uploads 目录下所有 JPG 和 PNG 图片:
find /www/wwwroot/example.com/wp-content/uploads/ -type f \( -name "*.jpg" -o -name "*.png" \) | while read f; do
if [ ! -f "${f%.*}.webp" ]; then
cwebp -q 80 "$f" -o "${f%.*}.webp"
fi
done
-q 80 表示压缩质量为 80,画质和体积比较均衡。
执行后可以用 find /www/wwwroot/example.com/wp-content/uploads/ -name "*.webp" | wc -l 统计生成数量。
对于之后新增的图片,可以把这个脚本放到 crontab 里每天执行一次,新图片会被自动转换,已转换的也不会重复处理。
最容易踩的四个坑
1. 忘记加 Vary Accept 响应头
如果省略 add_header Vary Accept;,CDN 和浏览器可能会把 WebP 响应缓存后发给不支持 WebP 的设备,导致图片打不开。
加了这一行,缓存节点才会根据 Accept 头区分响应内容。
2. CDN 回源时没有透传 Accept 头
使用 CDN 时,请确认回源配置里携带了原始请求头,尤其是 Accept。
如果 CDN 自己缓存并响应了 .html 或 .js 的 Accept 头,WebP 判断就会失效。
3. 图片文件权限不足
WebP 文件生成后,需要保证 Nginx 运行用户(通常是 nginx 或 www)有读取权限。
执行 chown -R www:www /www/wwwroot/example.com/wp-content/uploads/ 可解决大多数权限问题。
4. 误改导致 404
try_files $uri$webp_suffix $uri =404; 中,=404 是最后兜底,
不能写成 try_files $uri$webp_suffix =404;,
否则不支持 WebP 的浏览器访问 JPG 时会直接 404。
怎么确认配置真的生效了
配置完成并重载 Nginx 后,在服务器上执行下面两条命令:
curl -I -H "Accept: image/webp" https://example.com/wp-content/uploads/photo.jpg
curl -I https://example.com/wp-content/uploads/photo.jpg
第一条命令带上了 Accept: image/webp,预期得到 Content-Type: image/webp;
第二条不带这个请求头,预期仍然返回 image/jpeg。
只要两条结果不同,说明图片格式自适应输出已经生效。
建议在浏览器无痕模式里再访问一次图片地址,按 F12 打开开发者工具查看响应头,确认 Content-Type 是 image/webp 且响应头中包含 Vary: Accept。
如果你配置后访问图片报 404,优先检查三处:map 是否写在了 http 块、location 正则是否正确、.webp 文件是否真实存在。
排除这三点后,绝大多数问题都能解决。