图片优化 #
图片优化概述 #
Vercel 提供内置的图片优化服务:
text
┌──────────────────────────────────────────────────────┐
│ │
│ 原始图片 │
│ ┌─────────────────┐ │
│ │ 5MB PNG │ │
│ │ 4000x3000 │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ Vercel 图片优化 │
│ ┌─────────────────┐ │
│ │ 压缩 + 格式转换 │ │
│ │ 尺寸调整 │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ 优化后图片 │
│ ┌─────────────────┐ │
│ │ 100KB WebP │ │
│ │ 800x600 │ │
│ └─────────────────┘ │
│ │
└──────────────────────────────────────────────────────┘
优化功能 #
| 功能 | 说明 |
|---|---|
| 自动压缩 | 减小文件大小 |
| 格式转换 | WebP/AVIF 自动转换 |
| 尺寸调整 | 按需生成尺寸 |
| 响应式 | 适配不同设备 |
| 缓存 | 边缘缓存加速 |
Next.js Image 组件 #
基本使用 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/hero.jpg"
alt="Hero image"
width={800}
height={600}
/>
)
}
远程图片 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<Image
src="https://example.com/image.jpg"
alt="Remote image"
width={800}
height={600}
/>
)
}
next.config.js 配置:
javascript
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
port: '',
pathname: '/images/**',
},
],
},
}
填充模式 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<div style={{ position: 'relative', width: '100%', height: '400px' }}>
<Image
src="/hero.jpg"
alt="Hero image"
fill
style={{ objectFit: 'cover' }}
/>
</div>
)
}
响应式图片 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/hero.jpg"
alt="Hero image"
width={800}
height={600}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
)
}
优先加载 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/hero.jpg"
alt="Hero image"
width={800}
height={600}
priority
/>
)
}
懒加载 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/gallery/1.jpg"
alt="Gallery image"
width={400}
height={300}
loading="lazy"
/>
)
}
占位符 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<>
<Image
src="/hero.jpg"
alt="Hero image"
width={800}
height={600}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j/4AAQ..."
/>
<Image
src="/hero.jpg"
alt="Hero image"
width={800}
height={600}
placeholder="empty"
/>
</>
)
}
图片配置 #
next.config.js #
javascript
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
formats: ['image/avif', 'image/webp'],
minimumCacheTTL: 60,
dangerouslyAllowSVG: true,
contentDispositionType: 'attachment',
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
remotePatterns: [
{
protocol: 'https',
hostname: '**.example.com',
},
],
},
}
配置说明 #
| 配置项 | 说明 |
|---|---|
deviceSizes |
设备宽度断点 |
imageSizes |
图片宽度选项 |
formats |
输出格式优先级 |
minimumCacheTTL |
最小缓存时间(秒) |
dangerouslyAllowSVG |
允许 SVG 图片 |
remotePatterns |
远程图片白名单 |
Vercel 图片 API #
直接使用 API #
text
/_next/image?url=/hero.jpg&w=800&q=75
参数说明 #
| 参数 | 说明 | 示例 |
|---|---|---|
url |
图片路径 | /hero.jpg |
w |
宽度 | 800 |
q |
质量(1-100) | 75 |
外部图片 API #
javascript
fetch('/api/image?url=https://example.com/image.jpg&w=800&q=75')
图片优化策略 #
格式选择 #
text
┌─────────────────────────────────────────┐
│ 图片格式优先级 │
├─────────────────────────────────────────┤
│ AVIF → 最佳压缩,新浏览器支持 │
│ WebP → 良好压缩,广泛支持 │
│ PNG → 无损,透明背景 │
│ JPEG → 照片,有损压缩 │
│ GIF → 动图 │
└─────────────────────────────────────────┘
质量设置 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<>
<Image src="/photo.jpg" alt="Photo" width={800} height={600} quality={90} />
<Image src="/thumbnail.jpg" alt="Thumbnail" width={200} height={150} quality={60} />
</>
)
}
尺寸策略 #
text
推荐尺寸:
├── 缩略图:150-300px
├── 内容图:600-1200px
├── 大图:1200-2000px
└── 全屏:1920px+
响应式图片 #
sizes 属性 #
tsx
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/hero.jpg"
alt="Hero image"
width={800}
height={600}
sizes="
(max-width: 640px) 100vw,
(max-width: 1024px) 50vw,
33vw
"
/>
)
}
srcset 生成 #
Next.js Image 组件自动生成 srcset:
html
<img
srcset="
/_next/image?url=/hero.jpg&w=640&q=75 640w,
/_next/image?url=/hero.jpg&w=750&q=75 750w,
/_next/image?url=/hero.jpg&w=828&q=75 828w,
/_next/image?url=/hero.jpg&w=1080&q=75 1080w,
/_next/image?url=/hero.jpg&w=1200&q=75 1200w
"
/>
图片 CDN #
启用图片 CDN #
Vercel 自动为所有图片提供 CDN 加速:
text
┌──────────────────────────────────────────────────────┐
│ │
│ 用户请求图片 │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 边缘节点缓存 │ ← 命中缓存直接返回 │
│ └──────┬──────┘ │
│ │ 未命中 │
│ ▼ │
│ ┌─────────────┐ │
│ │ 图片优化服务 │ ← 处理并缓存 │
│ └─────────────┘ │
│ │
└──────────────────────────────────────────────────────┘
缓存策略 #
text
Cache-Control: public, max-age=31536000, immutable
缓存失效 #
bash
vercel env pull
vercel deploy --force
图片优化限制 #
免费计划 #
text
Hobby 计划:
├── 图片优化数量:1000 张/月
├── 最大图片大小:10MB
├── 最大图片尺寸:8000x8000px
└── 支持格式:JPEG, PNG, WebP, AVIF, GIF
Pro 计划 #
text
Pro 计划:
├── 图片优化数量:无限制
├── 最大图片大小:10MB
├── 最大图片尺寸:8000x8000px
└── 支持格式:全部
第三方图片服务 #
配置外部 Loader #
javascript
module.exports = {
images: {
loader: 'custom',
loaderFile: './imageLoader.js',
},
}
自定义 Loader #
javascript
export default function customLoader({ src, width, quality }) {
return `https://cdn.example.com/${src}?w=${width}&q=${quality || 75}`
}
使用 Cloudinary #
javascript
export default function cloudinaryLoader({ src, width, quality }) {
const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
return `https://res.cloudinary.com/demo/image/upload/${params.join(',')}/${src}`
}
最佳实践 #
图片优化清单 #
text
┌─────────────────────────────────────────┐
│ 图片优化最佳实践 │
├─────────────────────────────────────────┤
│ ✓ 使用 WebP/AVIF 格式 │
│ ✓ 设置合适的 sizes 属性 │
│ ✓ 首屏图片使用 priority │
│ ✓ 其他图片使用懒加载 │
│ ✓ 使用 blur placeholder │
│ ✓ 避免过大的原始图片 │
│ ✓ 合理设置 quality │
└─────────────────────────────────────────┘
性能指标 #
text
Core Web Vitals 图片相关:
├── LCP (Largest Contentful Paint)
│ └── 首屏大图影响 LCP
├── CLS (Cumulative Layout Shift)
│ └── 图片尺寸避免布局偏移
└── FID (First Input Delay)
└── 图片加载不阻塞交互
下一步 #
了解图片优化后,接下来学习 团队协作 探索 Vercel 的团队功能!
最后更新:2026-03-28