使用CloudFlare R2上传图片慢怎么解决

最近在做项目的时候,打算用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)。

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

相关推荐
Python编程学习圈19 小时前
Asciinema - 终端日志记录神器,开发者的福音
后端
bing.shao19 小时前
Golang 高并发秒杀系统踩坑
开发语言·后端·golang
壹方秘境19 小时前
一款方便Java开发者在IDEA中抓包分析调试接口的插件
后端
brzhang20 小时前
A2UI:但 Google 把它写成协议后,模型和交互的最后一公里被彻底补全
前端·后端·架构
开心猴爷20 小时前
iOS App 性能测试中常被忽略的运行期问题
后端
SHERlocked9320 小时前
摄像头 RTSP 流视频多路实时监控解决方案实践
c++·后端·音视频开发
AutoMQ21 小时前
How does AutoMQ implement a sub-10ms latency Diskless Kafka?
后端·架构
Rover.x21 小时前
Netty基于SpringBoot实现WebSocket
spring boot·后端·websocket
疯狂的程序猴21 小时前
用 HBuilder 上架 iOS 应用时如何管理Bundle ID、证书与描述文件
后端
ShaneD7711 天前
Redis 实战:从零手写分布式锁(误删问题与 Lua 脚本优化)
后端