最近在做项目的时候,打算用Cloud flare R2来存储图片,按照网上的教程配置好后,总算能够成功上传图片了,产品上线后,发现上传图片经常很慢,就对代码进行了优化。
1.使用edge function上传图片
edge function号称边缘函数,说会提升性能。
ini
// Edge Runtime 配置
export const runtime = 'edge';
export const regions = ['hkg1'];
但是我按照这种方式配置后,发现上传速度并没有什么提升。
2.先压缩图片再上传
难道是图片太大了,导致上传慢,于是我采用前端压缩的方式进行上传
ini
export async function compressImage(
file: File,
options: CompressionOptions = {}
): Promise<File> {
const opts = { ...defaultCompressionOptions, ...options };
// 如果不是图片文件,直接返回原文件
if (!file.type.startsWith('image/')) {
return file;
}
return new Promise((resolve, reject) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
try {
// 计算压缩后的尺寸
let { width, height } = img;
// 如果图片尺寸超过最大限制,按比例缩放
if (width > opts.maxWidth! || height > opts.maxHeight!) {
const ratio = Math.min(opts.maxWidth! / width, opts.maxHeight! / height);
width = Math.floor(width * ratio);
height = Math.floor(height * ratio);
}
// 设置画布尺寸
canvas.width = width;
canvas.height = height;
// 绘制压缩后的图片
ctx?.drawImage(img, 0, 0, width, height);
// 转换为 Blob
canvas.toBlob(
(blob) => {
if (!blob) {
reject(new Error('图片压缩失败'));
return;
}
// 检查文件大小是否超过限制
const sizeMB = blob.size / (1024 * 1024);
if (sizeMB > opts.maxSizeMB!) {
// 如果仍然太大,进一步降低质量
const newQuality = Math.max(0.1, opts.quality! * 0.7);
canvas.toBlob(
(newBlob) => {
if (!newBlob) {
reject(new Error('图片压缩失败'));
return;
}
const compressedFile = new File([newBlob], file.name, {
type: file.type,
lastModified: Date.now()
});
resolve(compressedFile);
},
file.type,
newQuality
);
} else {
const compressedFile = new File([blob], file.name, {
type: file.type,
lastModified: Date.now()
});
resolve(compressedFile);
}
},
file.type,
opts.quality
);
} catch (error) {
reject(error);
}
};
img.onerror = () => {
reject(new Error('图片加载失败'));
};
// 创建图片对象
const reader = new FileReader();
reader.onload = (e) => {
img.src = e.target?.result as string;
};
reader.onerror = () => {
reject(new Error('文件读取失败'));
};
reader.readAsDataURL(file);
});
}
修改完代码后,在本地测试感觉是快了不少,于是马上上线测试,发现还是有点慢。 又各种查资料,看来还是Cloud flare R2配置的问题。
添加自定义域名:
在R2 Object storage中的setting页面进行配置(为了和主域名区分,请使用子域名,比如cdn.example.com)。

配置好自定义域名之后,再修改环境变量就好啦。 现在去尝试下上传图片,明显快多了。