이미지 최적화

심채운·2024년 1월 10일
0

프로젝트

목록 보기
1/5
post-thumbnail

프로젝트를 진행하던 중 사용자가 악의로 고화질의 사진을 여러개 올렸을 때 S3의 비용 부담, 서버의 과부화, 렌더링의 시간 등을 고려해 이미지 최적화를하면 좋겠다고 생각해 최적화를 진행했다.

우선 사용자가 이미지를 업로드 했을 때, 이미지 사이즈를 압축해주는 라이브러리인 Browser-image-compression이라는 라이브러리를 사용했다.

react-image-file-resizer와 비교를 해본 결과 browser-image-compression이 사용도가 더 높아 정보가 많을 것이라고 판단

사용법은 압축하고자 하는 파일과 옵션을 설정하고 imageCompression 비동기 함수를 사용해 반환된 Blob객체를 가지고 원하는 로직대로 처리하면 된다.
나는 imgList가 있었고 반복문을 통해 파일들을 처리했다. api가 Blob객체가 아닌 file객체이므로 file객체로 변환 후 배열을 압축된 이미지들이 담긴 배열을 return 했다.

const resizeImage = async (files: File[]) => {
    const options = {
      maxSizeMB: 1,
      maxWidthOrHeight: 1920,
      useWebWorker: true,
    }
    try {
      const compressedImageList: File[] = []

      for (const file of files) {
        const compressedBlob = await imageCompression(file, options)

        // Blob 객체를 File 객체로 반환
        const compressedFile = new File([compressedBlob], file.name)
        compressedImageList.push(compressedFile)
      }
      // 압축된 이미지 리턴
      return compressedImageList
    } catch (error) {
      alert('이미지 압축 중 오류가 발생했습니다. 다시 시도해 주세요.')
    }
  }
const handleImagesChange = async (e: ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      const files = Array.from(e.target.files)

      if (files.length > 5) {
        alert('사진은 최대 5개입니다.')
        return
      } else if (files) {
        const newImages: File[] = [...files]
        const compressedImageList = await resizeImage(newImages)

        if (compressedImageList) {
          setFormData({
            ...formData,
            thumbnailImage: compressedImageList[0],

            imageFiles: compressedImageList.slice(1),
          })
          setThumbnail(URL.createObjectURL(compressedImageList[0]))
          setImgList(compressedImageList.slice(1).map((image) => URL.createObjectURL(image)))
        }
      }
    }
  }

위의 코드 처럼 이미지들을 핸들링하는 함수와 압축하는 함수를 따로 빼서 사용했다.




콘솔창을 보면 알겠지만 현재 이 지구 이미지는 약 1300KB이고 압축하면 880KB이다. 압축률은 약 32% 정도 된다. 한 두장이면 그러려니하고 넘어갈 수 있지만 이러한 사진들이 5장씩 사용자가 100명이라고만 해도 엄청 많은 비용이 발생한다.

극단적으로 사용해본 결과 이미지의 용량이 크면 클수록 압축하는 효과가 크다. 결과는 아래에 있다.


이 사진 같은 경우에는 원래 용량이 약 4MB이지만 610KB로 압축했다. 압축률은 약85% 정도 된다.

통신 속도 또한 약 26.65% 향상 했다. 아무래도 큰 이미지는 더 많은 데이터를 전송해야 하기 때문에 통신에 더 많은 시간이 소요될 수 있다.

이렇게 이미지를 최적화 함으로써 S3의 비용절감 효과를 기대할 수 있을 뿐더러, 더 빠른 통신 속도로 화면에 더 빠르게 렌더링을 할 수 있으며, 서버에게 과부화를 들 줄 수 있다.

이 외에도 webp를 이용한 최적화, lazy-loading을 이용한 최적화도 있지만 이 부분은 다음프로젝트에 적용하고 블로그에 올려보도록 하겠다.

profile
불가능, 그것은 사실이 아니라 하나의 의견일 뿐이다. - 무하마드 알리

0개의 댓글