前端图片压缩实战:体积直降 80%,LCP 提升 2 倍_前端图片压缩效率
本文提供 3 套完整方案(原生 Canvas、轻量级库、批量脚本),全部 零后端依赖,支持 WebP、JPEG、PNG、GIF,可直接搬进项目。
1️⃣ 方案 A:原生 Canvas 压缩(零依赖)
1.1 核心 30 行函数
/** * 将 File 压缩成 Blob * @param {File} file 原文件 * @param {Object} opts 配置 * maxWidth: 最大宽度(px) * maxHeight:最大高度(px) * quality: JPEG/WebP 质量 0-1 * @returns {Promise} 压缩后 Blob */async function compressImage(file, opts = {}) { const { maxWidth = 800, maxHeight = 600, quality = 0.8 } = opts; return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => { const canvas = document.createElement(\'canvas\'); const ctx = canvas.getContext(\'2d\'); // 等比缩放 let { width, height } = img; if (width > maxWidth || height > maxHeight) { const scale = Math.min(maxWidth / width, maxHeight / height); width *= scale; height *= scale; } canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); canvas.toBlob(resolve, file.type === \'image/png\' ? \'image/png\' : \'image/jpeg\', quality); }; img.onerror = reject; img.src = URL.createObjectURL(file); });}
1.2 调用示例
<input type=\"file\" id=\"file\" accept=\"image/*\" /><button onclick=\"handle()\">压缩并预览</button><canvas id=\"canvas\" style=\"border:1px solid #000;max-width:100%;\"></canvas><script>async function handle() { const file = document.getElementById(\'file\').files[0]; if (!file) return; const blob = await compressImage(file, { maxWidth: 800, quality: 0.7 }); const url = URL.createObjectURL(blob); document.getElementById(\'canvas\').src = url; console.log(`压缩前 ${(file.size/1024).toFixed(1)}KB → 压缩后 ${(blob.size/1024).toFixed(1)}KB`);}</script>
2️⃣ 方案 B:Compressor.js 一行搞定(推荐)
<script src=\"https://cdn.jsdelivr.net/npm/compressorjs@1.2.1/dist/compressor.min.js\"></script><input type=\"file\" id=\"uploader\" accept=\"image/*\" multiple /><script>document.getElementById(\'uploader\').addEventListener(\'change\', e => { Array.from(e.target.files).forEach(file => { new Compressor(file, { quality: 0.7, maxWidth: 1024, maxHeight: 1024, convertSize: 500000, // >500KB 转 WebP success(result) { console.log(`${(file.size/1024).toFixed(1)}KB → ${(result.size/1024).toFixed(1)}KB`); // 可直接 `fetch(\'/upload\', { method:\'POST\', body: result })` }, error(err) { alert(err.message); } }); });});</script>
3️⃣ 方案 C:批量脚本(Node CLI)
3.1 安装依赖
npm i -D imagemin imagemin-mozjpeg imagemin-pngquant imagemin-webp
3.2 一键压缩目录
// compress.jsimport imagemin from \'imagemin\';import imageminMozjpeg from \'imagemin-mozjpeg\';import imageminPngquant from \'imagemin-pngquant\';import imageminWebp from \'imagemin-webp\';(async () => { const files = await imagemin([\'src/images/*.{jpg,png}\'], { destination: \'dist/images\', plugins: [ imageminMozjpeg({ quality: 75 }), imageminPngquant({ quality: [0.6, 0.8] }), imageminWebp({ quality: 75 }) ] }); console.log(`压缩完成:${files.length} 张图片`);})();
执行:
node compress.js
4️⃣ 浏览器兼容 & 注意事项
loading=\"lazy\"
5️⃣ 一键脚本(前端上传 + 压缩)
git clone https://github.com/your-name/front-image-compress.gitcd front-image-compressnpm installnpm run dev
打开 http://localhost:3000
,拖拽图片即可实时压缩、预览、下载。
6️⃣ 总结一句话
前端图片压缩 = Canvas/Compressor 压缩 + WebP/Web Worker 优化 + 构建/部署链集成,按清单执行,体积直降 80%。