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 知识体系:图片压缩决策流程
说了这么多,你可能有点晕。没关系,我画了一张图,把整个决策逻辑串起来。你照着这个流程走,基本不会出错。
这张图的核心逻辑其实就两问:要不要透明?要不要兼容老浏览器? 回答完这两个问题,格式基本就定了。剩下的就是调压缩参数了。
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