2、图片压缩基础:有损 vs 无损压缩,常见图片格式对比

做界面移植,图片压缩是绕不开的坎。我记得刚入行那会儿,总觉得图片嘛,能看就行。直到有一次,一个 H5 活动页因为几张高清图,加载了快 10 秒,被产品经理追着骂了一下午。从那以后,我养成了一个习惯:每张图落地前,必须过一遍压缩策略。

这一章,咱们就把图片压缩的底裤扒干净。说白了,就两件事:怎么压,和用什么格式存。

2.1 有损压缩 vs 无损压缩

这两个概念,你肯定听过。但它们的本质区别,很多人其实没搞透。

无损压缩,就像把一件羽绒服抽真空。体积变小了,但拿出来一抖,还是那件衣服,一针一线都不少。PNG、GIF、WebP(无损模式)都属于这一类。它通过消除数据冗余来减小体积,解压后能 100% 还原原始数据。

有损压缩,更像是把一件毛衣拆了,只保留关键部分的毛线,重新织成一件更小的马甲。样子看着差不多,但细节没了。JPEG、WebP(有损模式)、AVIF 都干这事。它通过丢弃人眼不敏感的色彩和细节信息,来换取更高的压缩率。

核心结论:

  • 需要透明通道、图标、文字截图 → 用无损(PNG / WebP 无损)
  • 照片、渐变背景、复杂纹理 → 用有损(JPEG / WebP 有损 / AVIF)
  • 图标和照片混排的场景 → 我建议优先考虑 WebP,它支持有损和无损两种模式

你可能会问:「那我能不能先无损存,再转有损?」当然可以。但要注意,有损压缩是不可逆的。一旦丢了细节,神仙也救不回来。我在项目中就吃过这个亏——设计师给了 PNG,我嫌大,直接转 JPEG 压到 30%,结果渐变背景出现了明显的色块断层。嗯,后来老老实实保留了原始 PSD。

2.2 常见图片格式对比

现在前端能用的图片格式,说多不多,说少不少。我按「从老到新」的顺序,一个一个说。

PNG(Portable Network Graphics)

老牌无损格式。支持透明通道,压缩率一般。适合图标、Logo、UI 切图。但体积偏大,一张全屏截图动不动就几 MB。

JPEG(Joint Photographic Experts Group)

有损压缩的鼻祖。压缩率极高,但不支持透明。照片、实拍图的首选。质量参数(quality)一般设 70-85 之间,肉眼几乎看不出区别,体积能省一半以上。

WebP

Google 推出的「全能选手」。同时支持有损和无损,支持透明通道,压缩率比 PNG 高 26%,比 JPEG 高 25-34%。兼容性?嗯,iOS 14+ 和 Android 4.0+ 都支持了。我个人习惯:新项目默认用 WebP,除非要兼容非常老的浏览器。

AVIF

后起之秀,基于 AV1 视频编码。压缩率比 WebP 还高 20-30%,支持 HDR、广色域、透明通道。但编码速度慢,兼容性还在爬坡。目前适合用在「对体积极度敏感,且用户设备较新」的场景。

我的选择建议:

如果你在做一个面向大众的 App 或 Web 应用,我建议:主力用 WebP,降级用 JPEG/PNG。AVIF 可以当作「锦上添花」的选项,通过 <picture> 标签做渐进增强。

2.3 格式对比速查表

下面这张表,我建议你收藏一下。每次选格式时拿出来看一眼,能省不少纠结的时间。

格式 压缩类型 透明通道 压缩率(相对) 兼容性 典型场景
PNG 无损 ✅ 支持 低(基准) 全平台 图标、Logo、UI 切图
JPEG 有损 ❌ 不支持 中 全平台 照片、实拍图
WebP(无损) 无损 ✅ 支持 比 PNG 高 26% Chrome / Edge / Firefox / Safari 14+ 替代 PNG
WebP(有损) 有损 ✅ 支持 比 JPEG 高 25-34% 同上 替代 JPEG
AVIF 有损/无损 ✅ 支持 比 WebP 高 20-30% Chrome 85+ / Firefox 93+ / Safari 16.4+ 极致压缩场景

避坑指南:

我曾经在项目中全量使用 AVIF,结果发现部分 Android 机型的 WebView 不支持,导致图片大面积空白。后来我加了一层 <picture> 降级处理,才解决问题。记住:新格式一定要做降级方案,别让用户看到白屏。

2.4 知识体系:图片压缩决策流程

说了这么多,你可能有点晕。没关系,我画了一张图,把整个决策逻辑串起来。你照着这个流程走,基本不会出错。

图片压缩决策流程 图片压缩决策流程 原始图片 是否需要透明通道? 是 否 PNG / WebP 无损 JPEG / WebP 有损 兼容老旧浏览器? 兼容老旧浏览器? 是 否 是 否 PNG(全兼容) WebP 无损 JPEG(全兼容) WebP 有损 / AVIF 输出压缩后的图片 提示:新项目建议默认 WebP,用 <picture> 标签做 JPEG/PNG 降级

这张图的核心逻辑其实就两问:要不要透明?要不要兼容老浏览器? 回答完这两个问题,格式基本就定了。剩下的就是调压缩参数了。

2.5 实战中的压缩参数建议

光知道格式还不够,参数调不好,照样白搭。我把自己常用的参数贴出来,你直接拿去用。

  • JPEG:质量 75-85。低于 60 会出现明显块状伪影,高于 90 体积暴涨但画质提升有限。
  • PNG:用 pngquant 或 TinyPNG 压缩,颜色数降到 256 色以内,体积能省 60-80%。
  • WebP 有损:质量 70-80。我实测过,75 的质量肉眼几乎看不出和原图的区别,体积只有 JPEG 的 60%。
  • WebP 无损:直接使用默认参数,通常能比 PNG 小 30% 左右。
  • AVIF:质量 50-70。它的编码器比较激进,50 的质量在很多场景下依然可接受。

一个小技巧:

我在项目中经常用 cwebp 命令行工具批量转 WebP。一行命令搞定整个文件夹:

# 批量转 WebP 有损,质量 75
for img in *.png; do
  cwebp -q 75 "$img" -o "${img%.png}.webp"
done