博客图片压缩实战:我用 Squoosh 把配图从 4.58MB 压到 258KB
先说问题。我给博客配图最早是「手机照片直接传」,一张 2400×1600 的照片约 5MB,文章页打开后图片半天刷新不出来,Chrome 开发者工具里一看,三张图片加起来就有 9.9MB 了。这不但拖慢加载,Core Web Vitals 里的 LCP(最大内容绘制)也会直接被拉爆,对搜索排名和阅读体验都是实打实的伤害。

▲ 这张图片已被压缩到 42.3KB,由于图片太长导致看不清可以右键图片在新标签页中打开图片查看。
这篇文章是我解决问题的完整记录:现在每张配图进博客前都走同一条流水线,成品体积普遍在 200KB 以内,单张处理时间不超过两分钟。全文都是实操步骤,跟着做一遍就能用。
我的选择:为什么是 WebP
格式上我试过 JPEG、PNG、WebP 三种,最后固定在 WebP,理由有四条:
- 同画质体积最小。 Google 官方数据是 WebP 比 JPEG 平均小 25%~35%,我自己的实测比这个还夸张(下文有对比表);
- 浏览器支持早已不是问题。 Chrome、Edge、Firefox、Safari 14 之后的版本全部支持,2026 年的今天基本不存在「用户打不开 WebP」的场景;
- 加载快是连锁收益。 图片体积小了,LCP 指标直接改善,Core Web Vitals 全绿,网页打开速度和 SEO 同时受益;
- 静态站没有服务端转码能力。 我的站是纯静态托管,没有服务器帮我按需转格式,提前把图处理好是唯一解,那就一步到位用最优格式。
所以我的规矩是:照片类一律 WebP,质量 75;只有屏幕截图(文字边缘多)才保留 PNG。
压缩工具:Squoosh,Google 出品的免费网页工具
压缩工具我推荐 Squoosh(squoosh.app),这里简单介绍一下,因为它值得被更多人知道:
- 出身好:Google Chrome Labs 团队开发的开源项目,代码公开在 GitHub 上;
- 零门槛:网页打开即用,不用注册、不用安装、完全免费、没有次数限制;
- 隐私友好:所有压缩计算都在你自己的浏览器里完成,图片不会上传到任何服务器——它是 PWA 应用,第一次打开后断网也能用;
- 所见即所得:界面中间有一条对比滑块,左边是原图、右边是压缩结果,可以放大到像素级检查画质,调参数时实时预览;
- 功能够全:支持 MozJPEG、OxiPNG、WebP、AVIF 等主流编码器,还能缩放尺寸、去 EXIF 元数据、减色。
同类工具我用过不少,最后留在收藏夹的只有它——免费、无广告、不传图、对比直观,没有第二个把这些全占齐的。

▲ Squoosh 压缩界面
实战:一张 3.8MB 照片的完整压缩步骤
下面是我处理一张典型手机照片(2400×1600,3.8MB)的每一步:
第一步:拖入照片。 打开 squoosh.app,把照片文件直接拖进页面,或者点中央区域选择文件。页面左侧立即显示原图,右侧默认给出压缩预览。
第二步:先缩尺寸。 在右侧设置面板勾选 Resize,宽度填 1600(高度留空自动等比)。为什么是这个数:博客正文栏宽通常不到 800 像素,1600 宽是留给高分屏 2 倍显示的余量,再大纯属浪费流量。这一步是整条流水线里收益最大的——像素数量少了 55%,比压质量有效得多。
第三步:选格式。 在 Compress 下拉框里选 WebP。
第四步:定质量。 Quality 我喜欢滑块拉到 75。你也可以选择 80 这是体积和画质的甜点位置:80 以下开始出现可察觉的涂抹感,80 以上体积涨得很快但画质提升越来越不明显。
第五步:拖滑块验收。 按住界面中间的对比滑块左右拖,重点看三个地方:头发丝这类高频细节、天空这类渐变色(最容易出现色带)、文字或边缘锐利的物体。WebP 质量 80 在这三处的表现都过关,就可以收工。
第六步:下载并重命名。 右下角显示压缩后的体积和压缩率,点下载按钮保存。文件名立刻改成小写英文、连字符分隔,比如 desk-cable-before.webp(为什么要这么较真命名,下面的坑会讲)。

▲ Squoosh 参数设置
实测:95% 的体积就这么没了
同一张照片,三个阶段的体积对比:
| 处理阶段 | 规格 | 体积 |
|---|---|---|
| 手机原图 | JPEG 2400×1600 质量 95 | 4.5 MB |
| 只缩尺寸 | JPEG 1600×1067 质量 80 | 412 KB |
| 缩尺寸 + WebP | WebP 1600×1067 质量 75 | 258 KB |
从 4.5MB 到 258KB,体积砍掉 95%。页面加载上,这张照片从「要等将近 4 秒」变成「随正文一起秒开」。一篇文章按三张配图算,总图片流量从 11MB 降到 600KB 不到——这就是为什么我愿意每张图多花两分钟。
截图类图片顺手说一句:截完先裁剪再压缩,把没用的窗口边框、任务栏裁掉,体积常常直接减半,比任何编码器都管用。
一个真实的坑:大写 .JPG 让我排查了一下午
流程定好之后我还栽过一个跟头,值得单独写,因为这个问题在 Windows 上开发的人几乎都会遇到。
某篇文章里我引用了 ,本地 npm run dev 一切正常,部署到 Cloudflare Pages 之后图片 404。缓存清了、路径对了、文件确认了「明明在」,排查了一下午,最后发现问题蠢到离谱:文件名实际是 desk.JPG——大写后缀。
原理是:Windows 文件系统大小写不敏感,本地开发时 desk.jpg 和 desk.JPG 被当作同一个文件,怎么引用都能打开;而 Cloudflare Pages 的服务端运行在 Linux 上,大小写敏感,desk.jpg ≠ desk.JPG,于是 404。
所以现在我的流水线里多了一步:进 public/images/ 之前统一改成小写文件名,并定期用一条命令检查漏网之鱼。Windows 上我用 PowerShell(注意要用区分大小写的 -cmatch,默认的 -match 不分大小写,查不出来):
Get-ChildItem public -Recurse -File | Where-Object { $_.Extension -cmatch '^\.(JPG|PNG|JPEG)$' }
输出为空才算干净。有输出就两种情况:文件还没被引用,直接改名;已经被文章引用了,改名时要把文章里的引用路径一起改,两头保持一致。
这里我就不放图片了,相信你们不会犯这种错误~
放进博客时的两个细节
图片文件处理好,往文章里放的时候还有两个细节,都是免费的性能分。
显式写宽高和懒加载:
<img src="/images/desk-cable-before.webp" alt="理线前的桌面" width="1600" height="900" loading="lazy">
写宽高的意义是防止 CLS(累积布局偏移):浏览器在图片加载完成前就知道要预留多大空间,页面不会在图加载的一瞬间「跳一下」。文章页图多的话不写宽高,CLS 很容易超标。loading="lazy" 让首屏之外的图延后加载,文章越长收益越大。两个属性都是零成本,没有理由不写。
别忘了 og:image。 文章头图还有第二个身份——社交分享卡片图,微信、Twitter 分享链接时抓的就是它。两个要求:尺寸建议 1200×630(各平台通用的裁切比例);它必须指向真实存在的文件。发布前把 og:image 的地址直接在浏览器打开看一眼,一秒钟的事,避免分享出去是裂图。
总结:两分钟一张的流水线
完整流程串一遍,以后每张图照着走就行:
- 截图先裁剪,裁掉无用边框;
- 拖进 Squoosh,Resize 到宽 1600;
- 格式选 WebP,Quality 定 80;
- 拖对比滑块验收细节,下载;
- 重命名为小写连字符格式,进
public/images/; - 文章里写清宽高、
loading="lazy"和 alt 描述。
图片是每个博主「每篇都要做」的事,值得花一次时间把流程固化下来。之后每篇文章省下的加载时间和流量,读者未必说得出原因,但一定能感觉到。