图片编码与常见格式
本篇建立前端对 图片编码 的最小心智模型:有损/无损差在哪、常见格式各自适合什么、Base64 为什么「看起来方便却更重」。缓存怎么命中见 浏览器缓存,本篇不重复强缓存细节。
像素与色彩直觉
| 概念 | 直觉 |
|---|---|
| 位图(raster) | 按像素存:JPEG / PNG / WebP / AVIF / GIF |
| 矢量(vector) | 按几何描述:SVG;放大不糊,适合图标/插画 |
| RGB + Alpha | 颜色通道 + 可选透明度;是否支持透明取决于格式 |
| 分辨率 | 宽×高越大,未压缩体积大致按像素数涨;编码再决定文件最终多大 |
面试一句话:格式决定「怎么压、能不能透明/动画」;分辨率决定「有多少像素要压」。
有损 vs 无损
| 有损 | 无损 | |
|---|---|---|
| 做法 | 丢掉人眼不敏感的细节换体积 | 压缩可逆,解压后与原像素一致(在该格式语义下) |
| 观感 | 高质量时几乎看不出;压狠了糊、块状伪影 | 边缘/文字更稳,体积通常更大 |
| 典型 | JPEG、有损 WebP/AVIF | PNG、无损 WebP、(多数场景下的)SVG 源 |
选型不是「无损总更好」:照片用有损往往更划算;图标、UI 切图、需精确像素时更偏向无损或矢量。
常见格式对比
| 格式 | 压缩 | 透明 | 动画 | 典型用途 | 兼容性直觉 |
|---|---|---|---|---|---|
| JPEG | 有损 | 否 | 否 | 照片、复杂渐变图 | 极广 |
| PNG | 无损 | 是 | 否(APNG 另说) | 图标、UI、需透明的位图 | 极广 |
| GIF | 有限色(调色板) | 1-bit 透明 | 是 | 简单动图;色阶少 | 极广,体积/画质常不如现代方案 |
| WebP | 有损/无损 | 是 | 是 | 通用现代位图首选之一 | 现代浏览器普遍支持 |
| AVIF | 有损/无损 | 是 | 可 | 更高压缩率的照片/大图 | 新于 WebP,需评估目标用户 |
| SVG | 矢量(文本/XML) | 天然 | 可(CSS/SMIL 等) | 图标、插画、可主题化图形 | 广;复杂度高时 DOM/解析成本要当心 |
补充:
- JPEG 不适合:大面积纯色 UI、锐利文字、需要透明。
- PNG 不适合当照片主格式:无损对照片体积常偏大。
- GIF 动图:很多场景用短视频(MP4/WebM)或动画 WebP 更省。
- SVG:可被 CSS/JS 控制;若路径极复杂或内嵌巨大位图,优势会打折。
Base64 与 data URL
把二进制变成可放进文本(HTML/CSS/JS)的 ASCII:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
| 点 | 说明 |
|---|---|
| 体积 | Base64 大约膨胀 ~33%(另加 data: 头) |
| 缓存 | 写进 HTML/JS 的内联图,往往跟着文档一起缓存/失效,难单独强缓存一张图 |
| 请求 | 少一次独立图片请求;小图标可能划算,大图通常不划算 |
| 何时可用 | 极小图标、关键路径必须内联、构建期内联临界 CSS 背景等 |
| 何时别用 | 大图、多图、需要独立缓存与 CDN 的资源 |
和 浏览器缓存 的关系:独立 URL 的图片才能好好用 Cache-Control / 协商缓存;data URL 更像「嵌在文本里的字节」。
浏览器侧直觉
- 解码也花钱:文件下载完还要解码成位图进内存;大图、同页很多图会吃 CPU 与内存。
- 显示尺寸 ≠ 文件像素:用 3000px 宽的图塞进 300px 宽的盒子,白下传输与解码成本。
- 响应式与现代格式(点到为止):
<picture>
<source type="image/avif" srcset="hero.avif" />
<source type="image/webp" srcset="hero.webp" />
<img src="hero.jpg" alt="..." width="800" height="450" />
</picture>
srcset / sizes 按设备选分辨率;picture + type 做格式回退。细节以项目构建链为准,本篇只建立「有回退」的意识。
选型口诀
| 场景 | 优先考虑 |
|---|---|
| 照片 / 复杂渐变 | JPEG,或 WebP/AVIF(有损)+ JPEG 回退 |
| 图标 / 线稿 / 可缩放 | SVG;不行再 PNG / 无损 WebP |
| 需要透明的位图 | PNG 或 WebP |
| 简单动图 | 动画 WebP / 短视频;GIF 仅兼容兜底 |
| 必须塞进 HTML/CSS 且极小 | 可考虑 data URL;否则独立文件 |
一句话:先问透明、动画、是否照片;再问目标浏览器能不能吃 WebP/AVIF;最后才谈要不要 Base64。
面试速记
- 位图 vs 矢量:位图按像素;SVG 按几何,放大不糊,适合图标。
- 有损 vs 无损:有损丢细节换体积(照片常用);无损可逆(UI/透明切图常用)。
- JPEG:有损、无透明,适合照片;不适合锐利文字与透明。
- PNG:无损、可透明,适合图标/UI;照片往往体积偏大。
- WebP / AVIF:现代格式,通常同画质更小;用
picture做回退。 - GIF:能动画但色少、常更臃肿;动效优先 WebP 或视频。
- Base64:约增 33%,且难单独缓存;只适合极小内联资源。
- 解码成本:过大像素图即使 CSS 缩小,仍多花钱;匹配显示尺寸。