오랜만에 포스팅을 하게 되었습니다.
그동안 NowMeet 개발에 열중한 나머지 잠시 동안 잊고 있었네요 😥
이번에는 S3 Bucket에 파일을 업로드 하고자 할 때 용량을 압축 시키는 작업을 해볼까 합니다.
개발 목적 의도
- 기존에 2MB 파일을 S3에 upload 하고나서, 클라이언트에서 Image File 렌더링 시간이 2초 지연
- 때문에 Image를 바로 렌더링 시키기 위해 용량을 최소화 하기로 결정
1. ✔️ Resizing 로직 작성
- S3에 업로드 할 때 aws 내 내장되어 있는 reszie() 함수를 호출
먼저 npm을 통해 sharp 라이브러리를 설치해 줍시다.
npm i sharp
위 공식문서를 통해 내장되어 있는 기능들을 살펴 보시길 바랍니다.
그 다음 S3에 업로드 할 로직에 sharp 메서드를 추가해 줍니다.
async uploadFilesToS3(folder: string, files: Array<Express.Multer.File>) {
try {
// 파일 업로드 할 떄 설정 할 Option
const uploadPromises = files.map(async (file) => {
const imgResizingBuffer = await sharp(file.buffer)
.resize(2048, 2048, { fit: "inside", withoutEnlargement: true })
.webp({ quality: 80 })
.toBuffer();
// 2048 * 2048 해상도 유지 - Image Fit 유지 - webp 형식으로 저장
const key = `${folder}/${Date.now()}_${path.basename(file.originalname)}`.replace(/ /g, "");
const putCommand = new PutObjectCommand({
Bucket: this.S3_USER_PROFILES_BUCKET_NAME,
Key: key,
Body: imgResizingBuffer, // reszie시킨 Data를 Body에 담아 저장
ContentType: "image/webp",
});
// S3에 Upload
const s3Object = await this.s3Client.send(putCommand);
return { key, s3Object, contentType: "image/webp" };
});
return Promise.all(uploadPromises);
} catch (e) {
console.error("uploadFilesToS3", e);
throw new BadRequestException(`파일 업로드에 실패 했습니다 : ${e}`);
}
}
2. 🤚 이전 파일과 용량 비교
- 얼마나 잘 압축 되었는지 한 번 확인 해볼까요?
기존에 올렸던 파일과 용량을 확인 해보도록 하죠!
위 파일은 S3에 업로드 하기 전에 정보입니다. 2.13MB를 자랑하는 어마무시한 친구입니다.
S3에 업로드 했더니 15.3KB로 확 줄어든 것을 확인 할 수 있었고, 약 99% 정도 압축 되어 파일이 올라 갔습니다.
실제 Image 퀄리티를 한 번 비교 해보겠습니다.
왼쪽이 15.3KB 이미지고, 오른쪽이 2.13MB 원본 이미지 입니다.
resize 될 때 색이 약간 변조 되고 살짝 깨졌지만, 실제 앱 내에서는 Image size가 이렇게 크게 노출 될이 없습니다.
때문에 퀄리티 적인 측면에서 크게 손해 본다고는 할 수 없을거 같습니다.
마치며
- npm sharp 라이브러리를 통해 File을 여러 옵션을 통해 다양한 방법으로 압축 할 수 있는 것을 알아봤습니다.
- 특히 Image 렌더링에 지연 시간이 길어 진다면 도입 할 만한 기술이라고 생각합니다.