图片压缩实战总结:从踩坑到优化的全过程分享

鑫玉 优化 阅读 1,829
赞 11 收藏
二维码
手机扫码查看
反馈

我的写法,亲测靠谱

在前端开发中,图片压缩是一个常见的需求。我一般这样处理:首先,在用户上传图片时进行压缩,然后将压缩后的图片存储到服务器。这样既能保证图片质量,又能减少服务器存储压力。

图片压缩实战总结:从踩坑到优化的全过程分享

以下是我的代码实现:

// 使用FileReader读取文件
const fileInput = document.getElementById('file-input');
const compressedImage = document.getElementById('compressed-image');

fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.src = e.target.result;
      img.onload = () => {
        // 创建canvas元素
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');

        // 设置canvas的大小
        let width = img.width;
        let height = img.height;
        const maxWidth = 800; // 最大宽度
        const maxHeight = 600; // 最大高度

        if (width > maxWidth || height > maxHeight) {
          if (width > height) {
            height *= maxWidth / width;
            width = maxWidth;
          } else {
            width *= maxHeight / height;
            height = maxHeight;
          }
        }

        canvas.width = width;
        canvas.height = height;

        // 将图片绘制到canvas上
        ctx.drawImage(img, 0, 0, width, height);

        // 将canvas内容转换为Blob
        canvas.toBlob((blob) => {
          const compressedFile = new File([blob], file.name, { type: 'image/jpeg', lastModified: Date.now() });
          // 显示压缩后的图片
          const url = URL.createObjectURL(compressedFile);
          compressedImage.src = url;
        }, 'image/jpeg', 0.8); // 0.8是压缩质量
      };
    };
    reader.readAsDataURL(file);
  }
});

为什么这样写?因为这种方法可以在客户端直接对图片进行压缩,避免了将大图片上传到服务器再压缩的麻烦。而且,通过调整canvas的大小和压缩质量,可以灵活控制压缩后的图片大小和质量。

这几种错误写法,别再踩坑了

下面是一些我在实际项目中遇到的错误写法,建议避开这些坑。

  • 直接上传大图片: 直接上传大图片不仅会增加服务器的压力,还会导致用户体验差(加载时间长)。这种写法一定要避免。
  • 使用第三方库时不配置参数: 很多第三方库提供了丰富的配置选项,但很多人在使用时没有仔细阅读文档,直接使用默认配置。比如,使用compressor.js时,如果不配置quality参数,压缩效果可能不佳。
  • 压缩后不验证图片质量: 压缩后的图片质量可能会受到影响,如果不进行验证,可能会导致图片模糊或失真。建议在压缩后显示预览,让用户确认图片质量。
// 错误写法示例
// 直接上传大图片
const fileInput = document.getElementById('file-input');
fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  if (file) {
    // 直接上传大图片
    const formData = new FormData();
    formData.append('file', file);
    fetch('https://jztheme.com/api/upload', {
      method: 'POST',
      body: formData
    }).then(response => response.json()).then(data => {
      console.log(data);
    });
  }
});

这种写法虽然简单,但完全忽略了图片压缩的需求,非常容易出问题。

实际项目中的坑

在实际项目中,图片压缩还有一些需要注意的地方。

  • 跨域问题: 如果图片是从其他域名获取的,可能会遇到跨域问题。解决方法是在服务器端设置CORS头,或者使用代理服务器。
  • 移动端兼容性: 在移动端,不同设备的性能差异较大,需要特别注意压缩算法的性能。如果压缩算法过于复杂,可能会导致页面卡顿。
  • 图片格式支持: 不同浏览器对图片格式的支持不同,比如WebP格式在某些老版本浏览器中可能不被支持。因此,需要做好兼容性处理。

举个例子,我曾经在一个项目中遇到过跨域问题。当时我们的图片是从一个CDN获取的,但由于CDN没有设置CORS头,导致无法在canvas上绘制。最后,我们通过在服务器端设置CORS头解决了这个问题。

# 服务器端设置CORS头
Header set Access-Control-Allow-Origin "*"

折腾了半天才发现,原来问题出在这里。所以,遇到类似问题时,一定要仔细排查。

以上是我总结的最佳实践,有更好的方案欢迎评论区交流

以上就是我在图片压缩方面的一些实战经验和总结。希望对你有所帮助。如果有更好的方案或者不同的看法,欢迎在评论区交流。

这个技巧的拓展用法还有很多,后续我会继续分享这类博客。以上是我踩坑后的总结,希望对你有帮助。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论