-
选“体积最小可接受”的格式
├─ 矢量:≤ 1 kB 的小 icon → inline SVG(避免额外请求)
├─ 照片:WebP 优先(比 JPEG 小 25-35%),不支持时 -
压缩到底
├─ 构建链自动:imagemin / sharp / squoosh webpack/vite 插件
├─ 线上二次:CDN 提供 ?imageMogr2/format/webp/quality/75 这类参数
└─ 注意:压缩率 75-80 是视觉与体积的甜蜜点,再高压人眼可辨 -
响应式尺寸 —— 只下所需像素
<picture>
<source media="(max-width:640px)" srcset="hero-640.webp" type="image/webp">
<source media="(max-width:960px)" srcset="hero-960.webp" type="image/webp">
<img src="hero-1920.jpg" width="1920" height="1080" alt>
</picture>
配合 srcset+sizes 同样可行;关键把 `width`/`height` 写死,避免 CLS 抖动
- 延迟加载(LazyLoad)
├─ 浏览器原生:<img loading="lazy">(Chrome/Edge/Firefox 均支持,无需 JS)
├─ 更精细:IntersectionObserver 自写或直接用 lozad.js,支持 background-image、picture、video 海报帧
└─ 注意首屏任何图片都别 lazy,否则适得其反 - 预加载关键资源
- 占位 & 平滑过渡
├─ 小体积模糊占位:生成 20 px 宽的高斯模糊版本(约 1-2 kB),先铺背景,再 transition 到原图
├─ 骨架屏/色块占位:品牌主色调做 background-color,减少 CLS
└─ 不推荐 base64 大图内嵌,体积膨胀且无法缓存 - HTTP 层面
├─ HTTP/2 多路复用,雪碧图、域名分片反而恶化;单域名即可
├─ 缓存:Cache-Control: max-age=31536000, immutable 给图片加指纹名
└─ CDN:就近 + HTTP/3 + Brotli,静态图片也能压缩 10% 左右 - 服务端能力
├─ 自适应 WebP/AVIF:CDN 边缘根据 Accept 头自动回源转码
├─ 自动裁剪:/hero.jpg?w=800&h=400&fit=crop 一步拿到所需尺寸,避免前端拉原图再靠 CSS 裁
└─ 渐进式 JPEG(progressive JPEG)对首屏感知提升明显,大 banner 建议开 - JS 运行时优化
├─ 懒加载库若必须,请做 code-split + prefetch,防止交互时二次下载
├─ 图片轮播/画廊:滑动到第 N 张再加载,而不是一次性拉 50 张
└─ 虚拟滚动:长列表(商品图、相册)只渲染可视区域节点,内存和带宽双降 - 指标与监控
├─ 以 LCP、FID、CLS 为核心,用 PerformanceObserver 采集真实用户数据
├─ 用 Lighthouse CI / PageSpeed Insights 设门禁:新 MR 导致 LCP > 2.5 s 直接拒绝
└─ 把图片失败、重试、空 src 上报,防止“破图”拖慢体验