Large File Upload Optimization Strategies
大文件上传优化策略
1. Chunked/Resumable Uploads ⭐ (Recommended)
- 分块/可续传上传 ⭐(推荐)
Implementation Overview 实施概述
Break large files into smaller chunks (1-5MB each) and upload them sequentially or in parallel.
将大文件分割成 较小的块(每个 1-5MB),然后依次或并行上传。
Benefits 好处
- Resumable: If connection fails, resume from last successful chunk
支持断点续传:连接失败时可从上次成功的块继续上传 - Progress tracking: Real-time upload progress
进度追踪:实时上传进度 - Better UX: User can continue using the app while uploading
更佳用户体验:用户可以在上传时继续使用应用 - Network resilience: Small chunks are less likely to fail
网络韧性:小块更不易失败
Basic Implementation 基本实现
javascript
// Frontend - Chunked Upload
async function uploadLargeFile(file, chunkSize = 2 * 1024 * 1024) { // 2MB chunks
const totalChunks = Math.ceil(file.size / chunkSize);
const uploadId = generateUniqueId();
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
const start = chunkIndex * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
await uploadChunk(chunk, chunkIndex, totalChunks, uploadId);
updateProgress((chunkIndex + 1) / totalChunks * 100);
}
// Finalize upload
const fileUrl = await finalizeUpload(uploadId, file.name);
return fileUrl;
}
async function uploadChunk(chunk, chunkIndex, totalChunks, uploadId) {
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('chunkIndex', chunkIndex);
formData.append('totalChunks', totalChunks);
formData.append('uploadId', uploadId);
const response = await fetch('/api/upload-chunk', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error(`Chunk ${chunkIndex} upload failed`);
}
}
2. Background/Asynchronous Upload
- 背景/异步上传
Implementation 实现
Start upload immediately when file is selected, continue in background while user navigates.
文件选择后立即开始上传,在用户导航时在后台继续上传。
javascript
// Start upload immediately on file selection
document.getElementById('fileInput').addEventListener('change', (e) => {
const file = e.target.files[0];
if (file) {
// Start background upload
const uploadPromise = startBackgroundUpload(file);
// Store upload promise reference
window.pendingUpload = uploadPromise;
// Show upload progress
showUploadProgress(uploadPromise);
}
});
// Check upload status on page B
async function checkUploadStatus() {
const uploadId = localStorage.getItem('currentUploadId');
if (uploadId) {
const status = await fetch(`/api/upload-status/${uploadId}`);
const { isComplete, progress, fileUrl } = await status.json();
if (isComplete) {
return fileUrl;
} else {
// Still uploading, show progress
showUploadProgress(progress);
return null;
}
}
}
3. Client-Side Compression
- 客户端压缩