使用readAsDataURL过程中遇到的问题

在用户头像编辑项目中,使用FileReader的readAsDataURL方法预览大图片时,会导致浏览器卡顿。原因是生成的base64字符串过长,增大了渲染压力。为优化性能,采用URL.createObjectURL作为替代方案,它返回的url更高效,但在不再使用时需手动释放内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

用户头像编辑: 需要用户从本地选择图片后, 能在本地预览和简单编辑图片


问题描述

使用的readAsDataURL生成图片的本地预览地址。用户选择小图片时还好,一旦超过5M, 选择后会卡一下,后面的简单编辑(使用了图片的css属性clip)更是卡的不行

getImgSize(imgFile) {
  return new Promise((resolve, reject) => {
    let reader = new FileReader();
    reader.readAsDataURL(imgFile);
    reader.onload = function () {
      let image = new Image();
      image.src = reader.result;
      image.onload = function () {
        resolve({
          width: this.width,
          height: this.height,
          src: this.src,
        });
      };
    };
  });
},

原因分析:

FileReader.readAsDataURL(file)返回值是转化后的超长base64字符串(长度与要解析的文件大小正相关,且大于要解析的文件),用户选择的图片体积越大,浏览器渲染的压力就越大


解决方案:

使用URL.createObjectURL()代替,createObjectURL返回一段带hash的url,可以节省性能并更快速,只不过需要在不使用的情况下手动释放内存。

getImgSize(imgFile) {
  return new Promise((resolve, reject) => {
    let url = window.URL || window.webkitURL;
    let img = new Image();
    if (this.imgLocalSrc) {
      url.revokeObjectURL(this.imgLocalSrc);
    }
    this.imgLocalSrc = url.createObjectURL(imgFile);
    img.src = this.imgLocalSrc;
    img.onload = function () {
      resolve({
        width: this.width,
        height: this.height,
        src: this.src,
      });
    };
  });
},
### WangEditor 富文本编辑器图片上传缩放问题解决方案 WangEditor 是一款功能强大的富文本编辑器,在实际开发过程中,可能会遇到图片上传时的尺寸调整或压缩问题。以下是针对该问题的具体分析与解决方案。 #### 1. 自定义图片上传逻辑 通过设置 `uploadImgServer` 和 `customInsertImg` 参数可以实现自定义图片上传行为。可以在服务端处理图片之前对其进行裁剪、压缩操作[^1]。 ```javascript const E = window.wangEditor; let editor = new E('#editor'); // 设置图片上传地址 editor.config.uploadImgServer = '/your/upload/url'; // 添加自定义参数 editor.config.uploadImgHeaders = { token: 'xxx' // 可选,根据业务需求添加请求头 }; // 处理返回数据并插入图片 editor.config.customInsertImg = function (result, insertFn) { const imgUrls = result.data.map(item => item.url); // 假设后端返回的是数组结构 imgUrls.forEach(url => insertFn(url)); // 插入每张图片 }; ``` #### 2. 后端控制图片大小 在 PHP 接口层面,可以通过图像处理库(如 GD 或 Imagick)对上传的图片进行预处理后再保存至目标路径[^3]。以下是一个简单的例子: ```php public function uploadImage() { $targetDir = './uploads/'; if (!is_dir($targetDir)) mkdir($targetDir); $file = $_FILES['file']; list($width, $height) = getimagesize($file['tmp_name']); // 如果宽度超过指定值,则按比例缩小 if ($width > 1920 || $height > 1080) { $newWidth = min(1920, $width); $ratio = $newWidth / $width; $newHeight = intval($height * $ratio); $imageResized = imagecreatetruecolor($newWidth, $newHeight); $sourceImage = imagecreatefromstring(file_get_contents($file['tmp_name'])); imagecopyresampled( $imageResized, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height ); ob_start(); imagejpeg($imageResized, null, 85); // 输出JPEG质量为85% $content = ob_get_clean(); file_put_contents($targetDir . basename($file['name']), $content); } else { move_uploaded_file($file['tmp_name'], $targetDir . basename($file['name'])); } echo json_encode(['url' => "/$targetDir/" . basename($file['name'])]); } ``` #### 3. 客户端限制文件大小和分辨率 为了减少不必要的大图上传压力,可在前端增加校验机制来过滤不符合条件的图片[^4]。 ```javascript editor.config.onchange = function () {}; editor.config.uploadFileName = 'myFile'; // 文件字段名,默认为wangEditorH5File editor.config.maxFileSize = 2 * 1024 * 1024; // 单位字节,此处表示最大允许上传2MB的文件 editor.config.checkBeforeUploadImgs = async function (files) { let validFiles = []; files.forEach((file) => { const reader = new FileReader(); reader.onloadend = function () { const img = document.createElement('img'); img.src = reader.result; img.onload = function () { if (img.width >= 800 && img.height >= 600) { // 这里可以根据具体需求修改宽高阈值 validFiles.push(file); } }; }; reader.readAsDataURL(file); }); await sleep(500); // 等待异步加载完成 return Promise.resolve(validFiles); }; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } ``` --- #### 总结 上述方法分别从客户端和服务端两个角度解决了 WangEditor 中图片上传过程中的缩放问题。通过合理配置前后端交互流程以及引入必要的第三方工具支持,能够有效提升用户体验的同时降低资源消耗风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值