跳到主要内容

图片压缩与优化

面试速答(30 秒版 TL;DR)

图片优化不要只回答“转 WebP、压缩一下”,更完整的表达应该是:

  1. 先控制源图:上传前就不要给前端一张远超展示尺寸的大图。
  2. 再选格式:照片优先有损压缩格式,图标和透明素材优先无损或矢量格式。
  3. 按场景下发:同一张图给不同设备、不同屏幕密度、不同容器尺寸,应该返回不同版本。
  4. 再谈加载策略:首屏关键图优先,非首屏图懒加载,避免图片挤占关键带宽。
  5. 最后做稳定性优化:预留尺寸、防止 CLS、做好缓存和降级。

一句话总结:

图片优化的本质,不是把所有图片都压到最小,而是在“画质、体积、解码成本、加载时机、视觉稳定性”之间做场景化取舍。


为什么图片经常是性能大头?

图片是前端页面里最常见、也最容易失控的资源类型,因为它同时影响:

  • 网络传输体积
  • 解码和光栅化开销
  • 首屏 LCP
  • 页面稳定性 CLS

很多页面慢,不是 JS 太大,而是:

  • Hero 图原图几 MB
  • 列表页缩略图尺寸远大于展示尺寸
  • 移动端还在下发桌面大图
  • 懒加载做了,但尺寸没预留,页面跳动明显

所以图片优化通常要按链路回答,而不是只盯着“压缩率”。

先记优化链路,不要把“压缩”和“加载策略”混成一个点。


一、先做对一件事:不要把“源图问题”甩给浏览器

这是最常被忽略、但收益最大的部分。

1. 展示多大,就尽量提供多大的资源

如果页面上实际只显示 300 x 200 的卡片图,却下发 4000 x 3000 的原图,即使浏览器最后缩小显示,也已经付出了:

  • 下载成本
  • 解码成本
  • 内存占用

所以图片优化的第一原则不是“前端压缩”,而是“源图不要离谱”。

2. 一张图不应该只准备一个版本

真实页面中,同一资源通常会在不同场景下展示:

  • 列表缩略图
  • 详情页大图
  • 移动端窄屏
  • 高清屏 2x / 3x

如果所有场景共用同一张大图,通常不是最优方案。更合理的做法是让图片服务或构建流程生成多套尺寸。


二、格式怎么选:不要背结论,要知道为什么

1. JPEG / JPG

适合:

  • 照片
  • 色彩丰富的实拍图
  • 对极致清晰边缘要求不高的内容

特点:

  • 有损压缩
  • 压缩率通常不错
  • 不支持透明

2. PNG

适合:

  • 透明背景图片
  • 线条清晰、颜色块明显的图
  • 对无损保真更敏感的素材

特点:

  • 体积通常比照片类 JPEG 更大
  • 支持透明
  • 不适合拿来存大量照片素材

3. WebP

适合:

  • 大多数 Web 页面通用场景
  • 既想要较好压缩率,又希望兼顾透明能力

特点:

  • 既支持有损,也支持无损
  • 在很多图片场景下比 JPEG / PNG 更省体积
  • 常作为 Web 端默认优先格式

4. AVIF

适合:

  • 对极致体积敏感的图片密集型页面
  • 能接受更复杂编码链路的项目

特点:

  • 压缩效率通常更高
  • 但编码更慢,某些场景的解码和兼容策略也要评估

5. SVG

适合:

  • 图标
  • Logo
  • 简单插画
  • 几何图形

特点:

  • 本质是矢量描述
  • 缩放不失真
  • 不适合复杂照片内容

面试里更像工程师的说法是:

图片格式没有绝对最优,只有场景最优。照片看压缩率和感知画质,透明素材看透明支持和清晰边缘,图标优先矢量。


三、压缩不是越狠越好,关键是“感知质量”

图片压缩常见有两个方向:

方向含义适用场景
有损压缩牺牲部分细节换体积照片、背景图、内容图
无损压缩尽量不损失像素信息图标、界面元素、对边缘敏感的素材

1. 该怎么理解“压缩质量”?

不是把图片体积压到最小,而是让用户在正常观看距离下:

  • 看不出明显劣化
  • 不出现明显噪点、色块、边缘糊掉
  • 但体积显著下降

这也是为什么线上常常不会保留摄影原图级质量,而是使用“足够清晰”的版本。

2. 为什么有时候体积小了,页面反而不一定更快?

因为图片性能不只看传输,还要看:

  • 解码成本
  • 渲染成本
  • 是否阻塞关键资源

例如一张首屏大图虽然压得很小,但如果没有优先加载,它仍然可能拖慢 LCP;反过来,一张图即使体积不算夸张,但如果尺寸没预留,也会带来 CLS。


四、响应式图片:同一张图,应该按设备能力下发

响应式图片的目标不是“炫技”,而是让浏览器自己选更合适的版本。

最常见的是 srcset + sizes

<img
src="/images/card-640.webp"
srcset="/images/card-320.webp 320w, /images/card-640.webp 640w, /images/card-960.webp 960w"
sizes="(max-width: 768px) 100vw, 320px"
width="320"
height="180"
alt="课程封面"
/>

这段配置表达的是:

  • 小屏设备不必下大图
  • 大屏或高像素密度设备可以拿更高分辨率资源
  • 同时通过 widthheight 预留布局空间

如果还要做格式协商,可以结合 picture

<picture>
<source type="image/avif" srcset="/images/banner-768.avif 768w, /images/banner-1280.avif 1280w" sizes="100vw" />
<source type="image/webp" srcset="/images/banner-768.webp 768w, /images/banner-1280.webp 1280w" sizes="100vw" />
<img src="/images/banner-1280.jpg" width="1280" height="720" alt="活动横幅" />
</picture>

五、加载策略:谁该先到,谁该后到

1. 首屏关键图优先

对首页横幅、文章头图、商品主图这类会直接影响 LCP 的图片,关键不是“懒加载”,而是尽早拿到。

常见策略:

  • 让首屏关键图尽量出现在 HTML 早期
  • 避免依赖过深的 JS 才生成图片节点
  • 对真正关键的图片使用更高优先级加载策略

2. 非首屏图片懒加载

列表流、推荐区、评论区、瀑布流中的图片,通常更适合懒加载。

<img src="/images/product-480.webp" loading="lazy" width="240" height="240" alt="商品图片" />

懒加载的收益在于:

  • 减少首屏带宽竞争
  • 降低首屏解析后的图片请求数
  • 节省用户根本不会看到的资源下载

但要注意:

  • 首屏第一屏内的 LCP 图片通常不适合盲目 loading="lazy"
  • 图片未预留尺寸时,即使懒加载成功,也可能造成布局抖动

六、CLS 视角:图片优化不只是“更小”,还要“更稳”

很多页面首屏分数差,不是因为图片太慢,而是图片一出来就把布局顶开了。

最直接的做法是预留尺寸:

<img src="/images/avatar.webp" width="96" height="96" alt="用户头像" />

或者给容器固定宽高比:

.cover {
aspect-ratio: 16 / 9;
overflow: hidden;
}

.cover img {
width: 100%;
height: 100%;
object-fit: cover;
}

面试里可以直接说:

图片优化除了看 KB,还要看是否引起 CLS。体积小但布局乱跳,用户感知一样差。


七、工程里常见的图片优化流水线

真实项目通常不会依赖开发者手工处理每一张图片,而是把流程做成自动化。

这一套比“前端页面里临时写个压缩逻辑”更稳定,因为它能统一控制:

  • 尺寸规则
  • 格式策略
  • 压缩质量
  • 缓存命名

典型题 & 标准答法

Q1:图片优化有哪些常见手段?

我会按链路回答:先控制源图尺寸,再选合适格式,再做压缩,再生成多尺寸版本,然后按设备和布局下发,最后结合首屏优先、懒加载、尺寸预留和 CDN 缓存做整体优化。

Q2:为什么只把图片转成 WebP 还不够?

因为图片问题不只有格式。即使格式更先进,如果源图尺寸过大、首屏加载时机不对、没有响应式下发、没有预留尺寸,页面仍然可能慢或者抖。

Q3:如何避免图片导致 CLS?

给图片写明确的 widthheight,或给容器设置稳定的宽高比,让浏览器在图片真正下载完成前就能预留布局空间。

Q4:懒加载是不是所有图片都该开?

不是。首屏关键图如果也懒加载,可能会拖慢 LCP。懒加载更适合首屏外图片。


常见误区

  • 误区 1:图片优化等于转 WebP。 格式只是其中一步,源图尺寸和加载策略往往更关键。

  • 误区 2:只看文件体积,不看解码和渲染。 图片性能是“下载 + 解码 + 显示”的总和。

  • 误区 3:所有图都懒加载。 这会伤到真正影响首屏体验的关键图片。

  • 误区 4:缩略图直接用原图缩放显示。 浏览器只是显示变小,下载和解码成本并没有同步变小。


速记要点

  1. 图片优化先看源图尺寸,再看格式和压缩。
  2. 同一张图要按设备和布局生成多版本,而不是全端共用一张大图。
  3. 首屏关键图优先,非首屏图懒加载。
  4. 预留尺寸、防止 CLS,是图片优化里经常被忽略但很重要的一环。