6.8 KiB
6.8 KiB
S3存储性能零成本优化方案
📊 当前性能状况
根据测试结果:
- 公网(FRP): 0.04 MB/s,延迟 2829ms
- 内网(直连): 8.14 MB/s,延迟 8ms
- 问题: FRP穿透导致的网络瓶颈(内网比公网快203倍)
✅ 已实现的优化
-
内网用户自动使用内网地址 ✓
- 内网用户自动走内网,速度提升203倍
- 位置:
lib/url-rewrite.ts
-
分片上传 ✓
- 大文件(≥5MB)自动分片上传
- 支持断点续传
- 位置:
lib/chunk-upload.ts
-
图片压缩 ✓
- 预览图自动压缩为WebP格式
- 位置:
lib/image-processor.ts
🚀 零成本优化方案
1. 优化分片上传策略(推荐)⭐⭐⭐
目标: 减小分片大小,提高并发上传效率
当前配置:
- 分片大小: 5MB
- 阈值: 5MB以上才分片
优化方案:
// 在 components/upload/file-upload-handlers.ts
const CHUNK_THRESHOLD = 1 * 1024 * 1024 // 改为1MB(原来5MB)
const CHUNK_SIZE = 512 * 1024 // 分片大小改为512KB(原来5MB)
效果:
- 更小的分片 = 更快的单次上传 = 更好的进度反馈
- 512KB分片在0.04 MB/s下约需13秒,比5MB分片(125秒)快10倍
- 提高并发效率,减少超时风险
实施难度: ⭐ 简单(只需修改配置)
2. 优化图片压缩策略(推荐)⭐⭐
目标: 更激进的压缩,减少传输数据量
当前配置:
- 最大尺寸: 600x800
- 最大大小: 300KB
- 质量: 80
优化方案:
// 在 lib/image-processor.ts
const maxSizeKB = 150 // 从300KB降到150KB
const maxWidth = 400 // 从600降到400
const maxHeight = 600 // 从800降到600
const quality = 70 // 从80降到70
效果:
- 图片大小减少50%,传输时间减少50%
- 对于0.04 MB/s的网速,150KB图片约需4秒,300KB需8秒
实施难度: ⭐ 简单
3. 优化缓存策略(推荐)⭐⭐
目标: 延长缓存时间,减少重复下载
当前配置:
- 静态资源:
max-age=31536000(1年) ✓ - 上传文件:
max-age=31536000✓
优化方案:
- 确保所有S3返回的图片/文件都设置长期缓存
- 在
lib/s3.ts上传时设置缓存头
// 在 lib/s3.ts uploadToS3 函数中
const command = new PutObjectCommand({
Bucket: process.env.S3_BUCKET!,
Key: key,
Body: file,
ContentType: contentType,
ACL: 'public-read',
CacheControl: 'public, max-age=31536000, immutable', // 添加缓存头
})
效果:
- 用户第二次访问时直接从浏览器缓存加载,无需网络请求
- 减少90%以上的重复下载
实施难度: ⭐ 简单
4. 优化连接复用(推荐)⭐⭐
目标: 减少连接建立时间,提高效率
当前配置:
- S3客户端已配置连接超时和重试
优化方案:
// 在 lib/s3.ts
const s3Client = new S3Client({
// ... 现有配置
requestHandler: {
requestTimeout: 120000, // 增加到120秒(大文件需要)
connectionTimeout: 5000, // 减少到5秒(快速失败)
},
maxAttempts: 3, // 减少重试次数(从10降到3,快速失败)
retryMode: 'adaptive',
// 添加连接池配置
httpOptions: {
keepAlive: true,
keepAliveMsecs: 30000,
},
})
效果:
- 连接复用减少延迟
- 快速失败避免长时间等待
实施难度: ⭐⭐ 中等
5. 图片懒加载和预加载(推荐)⭐⭐
目标: 按需加载,减少初始加载时间
实施位置: components/home/MaterialCard.tsx
优化方案:
// 使用 Next.js Image 组件的懒加载
<Image
src={previewUrl}
alt={material.productModel}
width={300}
height={400}
loading="lazy" // 懒加载
placeholder="blur" // 模糊占位符
priority={false} // 非关键图片不优先加载
/>
效果:
- 初始页面只加载可见图片
- 减少初始加载时间50-70%
实施难度: ⭐⭐ 中等
6. 减少不必要的请求(推荐)⭐⭐⭐
目标: 合并请求,减少往返次数
优化点:
-
批量获取素材列表时合并预览图请求
- 当前:每个素材单独请求预览图
- 优化:使用CSS sprite或合并请求
-
减少API调用
- 使用React Query或SWR缓存API响应
- 减少重复的素材列表请求
实施难度: ⭐⭐⭐ 较复杂
7. 优化FRP配置(推荐)⭐⭐
目标: 虽然不能增加带宽,但可以优化配置提高效率
优化点:
-
启用压缩(如果FRP支持)
# frpc.toml [transport] compression = true # 启用压缩 -
优化连接池
[transport] poolCount = 10 # 增加连接池(如果当前较小) heartbeatInterval = 30 heartbeatTimeout = 90 -
使用TCP_NODELAY
- 减少延迟(如果FRP支持)
实施难度: ⭐⭐ 中等(需要服务器配置)
8. 前端预加载关键资源(推荐)⭐
目标: 提前加载用户可能访问的资源
实施位置: app/page.tsx 或 app/layout.tsx
优化方案:
// 预加载热门素材的预览图
useEffect(() => {
// 预加载前10个素材的预览图
const topMaterials = materials.slice(0, 10)
topMaterials.forEach(material => {
if (material.previewUrl) {
const link = document.createElement('link')
link.rel = 'prefetch'
link.href = material.previewUrl
document.head.appendChild(link)
}
})
}, [materials])
效果:
- 用户点击时图片已在缓存中
- 提升用户体验
实施难度: ⭐ 简单
📋 优化优先级
高优先级(立即实施)
- ✅ 优化分片上传策略 - 效果显著,实施简单
- ✅ 优化图片压缩 - 减少50%传输量
- ✅ 优化缓存策略 - 减少重复下载
中优先级(近期实施)
- ✅ 优化连接复用 - 提高效率
- ✅ 图片懒加载 - 减少初始加载
低优先级(长期优化)
- ✅ 减少不必要的请求 - 需要重构
- ✅ 优化FRP配置 - 需要服务器权限
- ✅ 前端预加载 - 锦上添花
🎯 预期效果
实施高优先级优化后:
- 上传速度: 用户体验提升(更小的分片,更快的反馈)
- 下载速度: 减少50%传输量(图片压缩)
- 重复访问: 减少90%网络请求(缓存)
- 总体体验: 提升2-3倍(综合效果)
💡 额外建议
-
用户提示优化
- 公网用户显示"内网用户可获得更快速度"提示
- 引导用户配置hosts使用内网地址
-
上传进度优化
- 显示预计剩余时间
- 显示当前网速
- 提供"稍后继续"功能(断点续传)
-
下载优化
- 大文件提供"稍后下载"功能
- 支持后台下载
- 下载队列管理