이미지 로딩 속도 최적화하기

이종훈·2025년 6월 21일
2

개발 일지

목록 보기
15/21
post-thumbnail

문제

모바일 청첩장 프로젝트에서 이미지를 AWS S3를 통해 관리하였습니다.
이때 이미지 조회 시 S3에 업로드한 URL로 접근하여 조회하는데, 해당 이미지를 로드하는데 시간이 오래 걸려 성능이 악화되는 문제를 겪게 되었습니다.


해결

해결 방법

이미지 업로드 시 이미지를 바로 S3로 업로드하지 않고, 특정 사이즈(썸네일)로 리사이징한 후 업로드하여 속도를 개선시킬 수 있습니다.

변경하고자 하는 이미지 업로드 방식은 다음과 같습니다.

  1. 사용자가 이미지를 업로드
  2. multer를 통해 이미지를 메모리(버퍼)에 임시 저장
  3. 버퍼에 저장한 이미지를 sharp를 통해 리사이징한 후 다시 버퍼에 저장
  4. 버퍼를 S3에 업로드

이때 이미지를 버퍼에 임시 저장 후 리사이징하는 이유는 sharp로 리사이징 하기 위해 버퍼가 필요하기 때문입니다.

구현

1) 이미지 -> 버퍼 저장 함수

export const imageUploader = multer({
  storage: multer.memoryStorage(),
  fileFilter: (req, file, cb) => {
    const extension = path.extname(file.originalname).toLowerCase();
    if (!allowedExtensions.includes(extension)) {
      return cb(new Error('허용되지 않은 이미지 형식입니다.'));
    }
    cb(null, true);
  },
  limits: {
    fileSize: 5 * 1024 * 1024, // 5MB
  },
});

-> 기존 함수(imageUploader)에서 이미지를 바로 S3에 업로드했지만, 이를 수정하여 임시로 버퍼에 업로드하도록 수정하였습니다.

2) 버퍼 -> S3 업로드 함수

export const uploadBufferToS3 = async ( buffer: Buffer, key: string, mimetype: string ): Promise<string> => {
  const bucket = process.env.AWS_BUCKET_NAME!;

  await s3.putObject({
      Bucket: bucket,
      Key: key,
      Body: buffer,
      ContentType: mimetype,
      ACL: 'public-read',
    }).promise();

  return `https://${bucket}.s3.${process.env.AWS_REGION}.amazonaws.com/${key}`;

};

-> 버퍼에 저장된 이미지를 S3로 업로드하는 함수입니다. 해당 함수는 Controller에서 버퍼의 이미지를 리사이징하여 다시 버퍼에 저장한 후 호출됩니다.

3) 이미지 리사이징

// 리사이즈 크기 및 포맷 지정
      const resizedBuffer = await sharp(file.buffer)
        .resize({ width: 450 })
        .toFormat('webp')
        .toBuffer();

버퍼에 저장된 이미지를 특정 크기로 리사이징하는 로직이며, 이미지 크기는 450px, 포맷은 webp로 리사이징하도록 설정하였습니다. 해당 크기로 설정한 이유는 성능과 비용면에서 최적의 크기와 포맷이기 때문에 설정했으며, 변경이 필요한 경우 수정할 수 있습니다. 또한 해당 로직은 Controller에서 구현되었으며, 이미지를 req로 넘겨받은 후 호출됩니다.

profile
종훈리의 개발일지

0개의 댓글