先说一组我们自己的数据。这个站的媒体库里躺着 1,093 张 JPG(合计 79.5 MB,平均 74 KB)、1,088 张 PNG(68 MB,平均 64 KB)、371 张 WebP(10.2 MB,平均 28 KB)。看着都不大,但同一张图分别存成 JPG 和 WebP,是 235 KB 对 31 KB——差了 7 倍。
图片是 WordPress 站点里体积占比靠前的资源。压不压、压到多少、用什么格式,这三件事在上传那一刻就定了,后面再改要重新处理整个媒体库。
这篇只讲操作:参数怎么定、用什么工具、WordPress 自己会生成什么、哪些坑会让你白忙一场。选插件的事另有一篇(见文末)。
一、上传前要定的三个参数
参数一:宽度。 手机和相机的原图动辄 4000px 宽,而页面根本显示不了那么宽。
先量一下你的正文区实际宽度。我们站的文章页是 711px(1440 视口、含左侧目录栏),宽屏模板通常在 780–900px。考虑到高分屏(2x),取 1.5–2 倍是合理的:内容区 711px,图片做到 1200–1400px 宽就够了。超过 1600px 对网页显示没有意义,只是让文件变大。
参数二:格式。
| 图片类型 | 建议格式 | 说明 |
|---|---|---|
| 照片、产品图、场景图 | WebP(回退 JPEG) | 同画质下比 JPEG 小 25%–35% |
| 截图、图表、带文字的图 | PNG 或 WebP 无损 | JPEG 会让文字边缘发虚 |
| 图标、Logo、线条插画 | SVG | 矢量,任意缩放不失真,几 KB |
| 需要透明底的图 | WebP 或 PNG | WebP 支持透明,体积通常更小 |
| 动图 | 短视频(MP4)替代 GIF | GIF 动图体积极大,10 秒能到几十 MB |
参数三:质量。 JPEG 用 75–82,WebP 用 75–80。低于 70 在渐变区域会出现明显色带,高于 85 体积涨得很快但肉眼几乎看不出差别。
压完别只看文件大小,放大到 100% 看一眼文字边缘和渐变区域。我们压过一张 370 KB 的产品图,降到 199 KB(−46%),放大检查后文字边缘仍然锐利——这个比例是可以接受的;同样参数压一张已经有噪点的照片,噪点会被放大得更明显,那就该把质量提回去。
二、三类图片的体积参考线
没有绝对标准,但超过下面这个量级,就该回头看看是不是尺寸给大了。
| 用途 | 建议宽度 | 体积参考 |
|---|---|---|
| 正文插图 | 1200–1400px | 100–200 KB |
| 卡片缩略图、列表图 | 600–800px | 40–80 KB |
| 首屏大图(Hero) | 1600–1920px | 200–350 KB |
| 图标、装饰元素 | 按显示尺寸或 SVG | 20 KB 以内 |
首屏大图是少数值得放宽的一项,因为它直接影响 LCP。但放宽不等于放任——一张 1.5 MB 的 Hero 图,在 4G 网络下要一两秒才能显示完,LCP 直接被拖到 2 秒以上。
三、上传前怎么压:三种工具
工具一:图形界面(适合零星处理)。 Squoosh 是网页版,拖进去就能调质量和格式,右侧实时显示体积。适合处理几张重点图。
工具二:命令行(适合批量)。 服务器上装了 cwebp 或 ImageMagick 的话,一条循环就能把整个目录转掉:
# JPEG → WebP,质量 78
find ./images -type f -name "*.jpg" | while read -r f; do
cwebp -q 78 "$f" -o "${f%.*}.webp"
done
# 用 ImageMagick 批量重编码,宽度限制在 1400px
mogrify -path ./out -resize "1400x>" -quality 82 ./images/*.jpg
-resize "1400x>" 里的 > 表示只缩小不放大,避免把小图拉大。
工具三:只有 PHP 的环境。 很多主机不给命令行工具,但 PHP 的 GD 扩展通常是开的。检查一下:
php -r 'var_dump(extension_loaded("gd"), gd_info()["WebP Support"]);'
两个都是 true,就可以用二十行脚本原地重编码(先备份):
<?php
$dir = '/path/to/uploads/2025/06';
$backup = '/path/to/backup/' . date('Ymd_His');
@mkdir($backup, 0755, true);
foreach (glob($dir . '/*.jpg') as $f) {
$before = filesize($f);
copy($f, $backup . '/' . basename($f));
$im = imagecreatefromjpeg($f);
if (!$im) { continue; }
imagejpeg($im, $f, 82); // 尺寸不变,只重编码
imagedestroy($im);
clearstatcache(true, $f);
printf("%s %.0f KB -> %.0f KB\n", basename($f), $before / 1024, filesize($f) / 1024);
}
我们就是用它处理了三张特色图:370 KB → 199 KB、352 KB → 193 KB,第三张 234 KB → 233 KB(原本已经压过,没有收益)。压缩率不是固定的,已经被压过的图再压一次基本没效果,这也能反过来判断一张图是否值得处理。
四、WordPress 会自己再生成好几份
这一点常被忽略:上传一张图,WordPress 默认会生成缩略图、中等、大图等多个尺寸,再加上主题和插件注册的尺寸,一张原图在磁盘上可能变成 4–6 个文件。
查看当前注册了哪些尺寸:
<?php
$extra = wp_get_additional_image_sizes();
foreach (get_intermediate_image_sizes() as $name) {
if (isset($extra[$name])) {
printf("%-22s %dx%d 裁剪:%s\n", $name, $extra[$name]['width'], $extra[$name]['height'], $extra[$name]['crop'] ? '是' : '否');
} else {
printf("%-22s 内置尺寸,宽高见 后台→设置→媒体\n", $name);
}
}
用不上的尺寸可以注销(放在主题的 functions.php 里):
add_filter('intermediate_image_sizes_advanced', function ($sizes) {
unset($sizes['medium_large'], $sizes['1536x1536'], $sizes['2048x2048']);
return $sizes;
});
注意两点:
- 只影响新上传的图,已经生成的旧文件不会消失。
- 不要随手用「重建缩略图」插件。它会重新处理整个媒体库,图片多的时候非常吃 CPU,在共享主机上可能直接把站点拖到 502。要跑就挑低峰期,先备份。
五、一个会悄悄吃掉缓存头的坑
用 WebP 插件批量转格式时,生成的文件名常是 图片名.png.webp 这种复合扩展名。看着只是命名奇怪,实际会让 nginx 的静态资源规则匹配不到:
# 很多站点只有这条,它匹配不到 .webp 结尾的文件
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
}
结果就是 WebP 文件没有任何缓存头,每次访问都要回源协商一次。我们在自己站上实测过:普通 JPG 有 Cache-Control: max-age=2592000,.png.webp 什么都没有。
补一条就正常:
location ~* \.(webp|avif|svg|ico|woff2|woff|ttf|otf)$ {
expires 30d;
access_log off;
}
宝塔环境建议把这条放在 vhost/nginx/extension/站点名/ 目录下,别直接改 vhost——面板保存站点设置会重写 vhost。相关细节(缓存规则分层、命中率验证)写在 WordPress CDN 指南里。
六、alt 文本和文件名
alt 不是给搜索引擎堆关键词的地方,它的作用是图片加载失败时告诉用户这里是什么。
- 产品图:写清「什么产品 + 关键特征」,例如「不锈钢法兰球阀 DN50 内螺纹」
- 装饰图、背景图:
alt=""(空值),让读屏软件跳过 - 图表截图:写清结论,例如「2025 年三类产品出口占比对比」
- 不要写成「球阀 球阀厂家 球阀价格 不锈钢球阀」这种关键词串,对用户没用
文件名同样值得改。IMG_20250612_143022.jpg 换成 stainless-steel-ball-valve-dn50.jpg,成本几秒钟,对图片搜索有实际帮助。
七、媒体库里没被使用的图,能不能删
能,但要先查清楚再删。用 SQL 找出没有被任何文章引用的附件:
SELECT p.ID, p.post_title
FROM wp_posts p
LEFT JOIN wp_postmeta m
ON m.meta_key = '_thumbnail_id' AND m.meta_value = p.ID
WHERE p.post_type = 'attachment'
AND m.meta_id IS NULL -- 不是任何文章的特色图
AND NOT EXISTS ( -- 正文里也没有引用它的地址
SELECT 1 FROM wp_posts c
WHERE c.post_status = 'publish'
AND c.post_content LIKE CONCAT('%', p.guid, '%')
)
LIMIT 50;
这条只是起点,不能直接拿来当「可删清单」。原因有三个:
- 特色图不在正文里,只在
_thumbnail_id里,漏掉这个条件会把所有特色图当成垃圾。我们站上那三张 300 KB 的特色图就属于这种情况——正文里搜不到,被「相关文章」卡片引用。 - 图片可能被页面构建器、自定义字段、CSS 背景引用,这些都不在
post_content里。 - 有些图是以前用过、现在暂时不用的,删了想恢复得从备份捞。
稳妥做法:筛出来的文件先移到临时目录,观察一两周,确认没有 404 再彻底删。
八、上传前的检查清单
- □ 宽度已缩到实际显示宽度的 1.5–2 倍,不超过 1920px
- □ 照片用 WebP 或 JPEG(质量 75–82),截图用 PNG 或 WebP 无损
- □ 单张体积在参考线内(正文图 200 KB 内,Hero 350 KB 内)
- □ 文件名改成语义化的英文,去掉了
IMG_前缀 - □ alt 写清楚是什么,装饰图留空
- □ 首屏大图确认没有超过 400 KB,且用了
fetchpriority="high" - □ 非首屏图片加了
loading="lazy" - □ 上传后确认缓存头正常(
curl -sI看cache-control)
前六项在上传前做,成本几分钟;上传后再补,就要动媒体库和页面,成本高一个量级。
九、继续读
- WordPress 图像优化插件推荐:七款插件横向对比,怎么选、怎么配、为什么只该装一个
- WordPress 网站速度优化指南:图片只是四段里的渲染段,先归因再动手
- WordPress 视频嵌入:视频属于同类问题,但代价比图片大得多
- WordPress CDN 指南:缓存头、命中率与真实 IP