图片是网页加载性能的主要瓶颈之一。根据 HTTP Archive 的数据,图片平均占网页总大小的 50% 以上。优化图片加载性能对于提升页面加载速度和用户体验至关重要。本文介绍几种常用的图片优化技术。
一、图片格式选择
选择合适的图片格式是优化的第一步:
| 格式 | 特点 | 压缩率 | 浏览器支持 | 适用场景 |
|---|---|---|---|---|
| JPEG | 有损压缩,支持渐进式 | 中 | 全部 | 照片、复杂图像 |
| PNG | 无损压缩,支持透明 | 低 | 全部 | 图标、简单图形 |
| WebP | 支持有损/无损,体积小 | 高 | 现代浏览器 | 通用场景 |
| AVIF | 最新格式,压缩率最高 | 极高 | 部分浏览器 | 前沿项目 |
| SVG | 矢量图形,无损缩放 | N/A | 全部 | 图标、插画 |
二、WebP 格式优化
WebP 是 Google 开发的图片格式,相比 JPEG 可以节省约 25-35% 的体积,相比 PNG 可以节省约 26% 的体积。
2.1 使用 标签
使用 picture 标签提供多种格式,浏览器会自动选择支持的最优格式:
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="描述文字">
</picture>
2.2 服务端转换
使用服务器中间件自动转换图片格式:
// Express middleware example
app.use('/images', (req, res, next) => {
const accept = req.headers.accept || '';
const ext = path.extname(req.path);
if (accept.includes('image/avif') && ext === '.jpg') {
req.url = req.url.replace('.jpg', '.avif');
} else if (accept.includes('image/webp') && ext === '.jpg') {
req.url = req.url.replace('.jpg', '.webp');
}
next();
});
💡 提示:WebP 和 AVIF 的兼容性越来越好,目前全球支持率超过 95%。对于老旧浏览器,可以使用 JPEG/PNG 作为降级方案。
三、响应式图片
使用 srcset 和 sizes 属性提供不同尺寸的图片:
3.1 srcset 基本用法
<img
src="image-600.jpg"
srcset="image-300.jpg 300w,
image-600.jpg 600w,
image-1200.jpg 1200w"
sizes="(max-width: 600px) 300px,
(max-width: 1200px) 600px,
1200px"
alt="描述文字"
>
3.2 使用 Picturefill 兼容性方案
对于不支持 srcset 的老旧浏览器,可以使用 Picturefill 库:
<script src="https://cdnjs.cloudflare.com/ajax/libs/picturefill/3.0.3/picturefill.min.js"></script>
四、图片懒加载
图片懒加载是指只在图片进入视口时才加载,减少初始页面加载时间。
4.1 原生懒加载
现代浏览器支持原生懒加载,只需添加 loading="lazy" 属性:
<img
src="image.jpg"
alt="描述文字"
loading="lazy"
>
4.2 自定义懒加载实现
对于需要更精细控制的场景,可以自定义实现:
class LazyLoad {
constructor() {
this.images = document.querySelectorAll('img[data-src]');
this.observer = new IntersectionObserver(
this.handleIntersection.bind(this),
{ threshold: 0.1, rootMargin: '100px' }
);
this.init();
}
init() {
this.images.forEach(img => {
this.observer.observe(img);
});
}
handleIntersection(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.removeAttribute('data-src');
this.observer.unobserve(img);
}
});
}
}
// Initialize
document.addEventListener('DOMContentLoaded', () => {
new LazyLoad();
});
4.3 使用占位图
在图片加载完成前显示占位图,提升用户体验:
<img
data-src="image.jpg"
src="placeholder.svg"
alt="描述文字"
class="lazy-image"
>
.lazy-image {
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
aspect-ratio: 16/9;
object-fit: cover;
transition: opacity 0.3s ease;
}
.lazy-image.loaded {
background: transparent;
}
五、图片压缩与优化
5.1 使用工具压缩
- Squoosh:Google 开发的在线压缩工具
- TinyPNG:PNG/JPEG 在线压缩
- Sharp:Node.js 图片处理库
- ImageOptim:Mac 图片压缩工具
5.2 自动化压缩
在构建过程中自动压缩图片:
// Webpack configuration example
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|webp)$/i,
use: [
{
loader: 'image-webpack-loader',
options: {
webp: { quality: 80 },
mozjpeg: { quality: 80 },
pngquant: { quality: [0.6, 0.8] }
}
}
]
}
]
}
};
六、CSS 优化技巧
6.1 使用 CSS Sprites
将多个小图标合并为一张图片,减少 HTTP 请求:
.icon {
background-image: url('sprites.png');
background-repeat: no-repeat;
}
.icon-home {
background-position: 0 0;
width: 32px;
height: 32px;
}
.icon-search {
background-position: -32px 0;
width: 32px;
height: 32px;
}
6.2 使用 CSS 渐变代替图片
对于简单的背景图案,使用 CSS 渐变代替图片:
.gradient-bg {
background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
}
.pattern-bg {
background-image:
linear-gradient(45deg, rgba(255,255,255,0.05) 25%, transparent 25%),
linear-gradient(-45deg, rgba(255,255,255,0.05) 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.05) 75%),
linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.05) 75%);
background-size: 20px 20px;
}
七、服务端优化
7.1 使用 CDN
使用 CDN 加速图片加载,选择支持自动格式转换的 CDN:
- Cloudflare:支持 Polish 自动优化
- Cloudinary:专业图片 CDN
- Imgix:支持实时图片处理
7.2 配置缓存策略
设置合理的缓存头,减少重复请求:
# Nginx configuration example
location ~* \.(jpg|jpeg|png|gif|webp)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept;
}
7.3 使用 HTTP/2 或 HTTP/3
HTTP/2 支持多路复用,可以同时加载多个图片而不阻塞:
# Nginx HTTP/2 configuration
server {
listen 443 ssl http2;
# ... 其他配置
}
八、性能监控与分析
8.1 使用 Lighthouse
Lighthouse 提供详细的图片优化建议:
// Using CLI
lighthouse https://example.com --view
// Using Node.js
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const results = await lighthouse(url, { port: chrome.port });
await chrome.kill();
return results;
}
8.2 使用 Web Vitals
监控核心 Web 指标:
import { getCLS, getFID, getLCP } from 'web-vitals';
getCLS(console.log);
getFID(console.log);
getLCP(console.log);
九、优化 Checklist
- ✅ 使用 WebP/AVIF 格式替代 JPEG/PNG
- ✅ 实现图片懒加载
- ✅ 使用响应式图片(srcset/sizes)
- ✅ 压缩图片至合适质量
- ✅ 设置正确的宽高比(aspect-ratio)
- ✅ 使用 CDN 加速
- ✅ 配置浏览器缓存
- ✅ 监控性能指标
十、总结
图片优化是前端性能优化的重要环节。通过选择合适的格式、实现懒加载、使用响应式图片等技术,可以显著减少页面加载时间,提升用户体验。
建议结合自动化工具和监控系统,持续优化图片性能。记住,优化是一个持续的过程,需要不断评估和调整。