引言
在现代网络应用中,优化图片是提高性能和用户体验的关键一环。Node.js 提供了多种库和工具来处理和压缩图片,本文将介绍几种主流的 Node.js 图片压缩库,并通过nestjs
框架使用sharp
库以及如何使用它来实现不同的压缩方式。
1. 图片压缩的重要性
在 Web 开发中,图片是网站加载速度的重要因素之一。过大的图片文件会导致页面加载缓慢,影响用户体验和 SEO。因此,使用有效的图片压缩工具至关重要,不但可以简约存储空间还能提高用户访问的速度,降低宽度消耗
2. 主流图片压缩库比较
在npmtrends.com对比了大家比较常用的npm压缩资源框架:canvas
,imagemin
,jimp
,sharp
能看到sharp
文档地址的下载是最大的,且优势有:
- 性能优越:
sharp
是基于 libvips 的图像处理库,性能出色,特别适合需要大规模图片处理的应用场景。 - 功能丰富: 提供了各种图像处理功能,如大小调整、格式转换、滤镜应用等。
- 简单易用: 提供了清晰的 API 和文档,方便开发者快速上手。
3. 使用 sharp
的简单示例
这里我们使用nestjs
框架创建应用支持图片上传,在nestjs入门实战(二):上传图片代码基础上添加sharp
对上传的图片进行压缩
最终压缩效果
在sharp
压缩质量75%
情况下的效果:原图为左文件大小3.1MB,压缩图为右文件大小144kb
安装sharp
依赖
由于sharp
最新版本最node版本要求(^18.17.0 or >= 20.3.0),我的node版本<18.17.0,所以这里选择了指定的历史版本 v0.32.1
npm i sharp@0.32.1 --save
创建压缩的图片位置
修改main.ts
入口文件,压缩后的图片放入根目录下的uploads/compress
// main.ts
import { NestFactory } from '@nestjs/core';
import * as express from 'express';
import * as path from 'path';
import { existsSync, mkdirSync } from 'fs';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
+ const uploadDir = path.join(process.cwd(), 'uploads', 'compress');
if (!existsSync(uploadDir)) {
mkdirSync(uploadDir, { recursive: true });
}
app.use('/uploads', express.static(path.join(process.cwd(), 'uploads')));
await app.listen(3000);
}
bootstrap();
创建压缩图片方法:compressImage
在src/upload/upload.service.ts
创建sharp
相关的压缩图片代码,参数:压缩质量为quality:75
尽量做到无损压缩,webp
方式压缩图片
// src/upload/upload.service.ts
import { Injectable } from '@nestjs/common';
import * as sharp from 'sharp';
import * as fs from 'fs';
import * as path from 'path';
@Injectable()
export class UploadService {
async compressImage(file: Express.Multer.File): Promise<string> {
const outputDir = path.join(process.cwd(), 'uploads/compress');
const fileName = file.filename;
const filePath = path.join(outputDir, file.filename);
const compressedImageBuffer = await sharp(file.path)
.webp({ quality: 75 })
.toBuffer();
fs.writeFileSync(filePath, compressedImageBuffer);
return fileName;
}
}
上传资源api添加压缩功能
在upload.controller.ts
中对上传图片进行压缩并返回压缩的图片和原图
// src/upload/upload.controller.ts
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { UploadService } from './upload.service';
@Controller('upload')
export class UploadController {
constructor(private readonly uploadService: UploadService) { }
@Post('/uploadImage')
@UseInterceptors(FileInterceptor('file', {
limits: { fileSize: Math.pow(1024, 2) * 5 } // 限制图片上传最大5MB
}))
async uploadImage(@UploadedFile() file) {
const fileName = await this.uploadService.compressImage(file);
return {
originImage: `http://localhost:3000/uploads/${fileName}`,
compressImage: `http://localhost:3000/uploads/compress/${fileName}`
};
}
}
Postman 上传图片
Postman中选中需要上传的图片访问:localhost:3000/upload/uploadImage
访问接口,服务返回原图地址和压缩图地址
压缩结果对比
上传的原图大小:3.1MB
压缩后的原图大小:144kb
原图与压缩图效果对比:
左边为原图效果,右边为压缩图效果
压缩策略
本文主要是以webp
方式,压缩质量75%
,实际开发中需要按照需求来配置压缩参数,一般的策略有:
-
小图片 (< 10KB) :
- 小体积的图片通常可以转换为 base64 编码直接嵌入到 HTML 或 CSS 中,减少 HTTP 请求次数,加快页面加载速度。适用于图标、小按钮等。
-
中等大小图片 (10KB - 500KB) :
- 对于中等大小的图片,推荐使用 WebP 格式进行压缩。WebP 格式可以显著减小文件大小,同时保持较高的视觉质量,适合用于网站的主要图片内容,如产品展示图、头图等。
-
大图片 (> 500KB) :
- 对于体积较大但不是特别重要的图片,可以考虑将图片质量降至 75 或更低的水平进行压缩,以减小文件大小,同时保持合理的视觉质量。这种策略适用于背景图、幻灯片等。
-
重要性与质量平衡:
- 对于重要且需要高质量展示的图片(如公司 logo、产品高清图片等),可以适度压缩以确保页面加载速度,但需要确保不影响视觉效果和用户体验。
-
自动化处理:
- 结合自动化工具和脚本,根据图片大小和类型自动选择合适的压缩策略。例如使用 Node.js 中的
sharp
或其他图片处理库,结合条件判断和批量处理功能来优化网站中的图片。
- 结合自动化工具和脚本,根据图片大小和类型自动选择合适的压缩策略。例如使用 Node.js 中的
总结
在选择图片压缩工具时,需要根据项目需求和性能考量进行选择。sharp
提供了出色的性能和灵活的功能,是处理和压缩图片的理想选择。