[ React ] 이미지 압축해서 성능 개선 ( browser-image-compression 라이브러리)

김문주·2025년 4월 21일
0

React

목록 보기
2/2
post-thumbnail

Browser Image Compression란?

서버에 업로드하기 전에 해상도저장 크기를 줄여 jpeg, png, webp, bmp 이미지를 압축할 수 있는 라이브러리입니다.

사용하게 된 배경

프로젝트에서 게시글 작성 시 이미지를 업로드하는 기능을 개발했습니다.

초기에 구현한 방식은 이미지를 압축 없이 원본 그대로 업로드하는 방식이었습니다.

하지만 테스트 과정에서 다음과 같은 문제를 발견했습니다.

  • 원본 파일 그대로 업로드 시 로딩 속도 저하
  • 렌더링 시간 증가로 UX 품질 저하

이를 해결하기 위해 클라이언트 측에서 먼저 이미지를 압축한 후 업로드하는 방식으로 개선했습니다.

사용 방법

압축을 원하는 파일과 옵션을 지정한 뒤, imageCompression 비동기 함수를 사용해 압축 시켜주면 됩니다!

코드 설명

💻수정 전 코드

const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files ? e.target.files[0] : null;
    if (file) {
      // 선택된 파일을 상태로 저장
      setSelctedImageFIle(file);
      const reader = new FileReader();
      reader.onload = () => {
        setPreviewImage(reader.result as string);
      };
      reader.readAsDataURL(file);
      // 파일 입력 필드 초기화
      e.target.value = '';
    }
  };

문제점

  • 압축되지 않은 파일 업로드
  • 큰 이미지 파일은 네트워크와 렌더링 성능에 부하를 줌

💻수정 후 코드

const handleImageChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    const maxFileSizeMB = 5;
    if (file.size > maxFileSizeMB * 1024 * 1024) {
      alert(`파일 크기가 ${maxFileSizeMB}MB를 초과했습니다.`);
      return;
    }
		// 이미지 옵션
    const options = {
      maxSizeMB: 0.2,
      maxWidthOrHeight: 1226,
      useWebWorker: true,
    };

    try {
      // 이미지 압축
      const compressedBlob = await imageCompression(file, options);
      const compressedFile = new File([compressedBlob], file.name, {
        type: file.type,
        lastModified: Date.now(),
      });

      setSelectedImageFile(compressedFile);

      // 미리보기 이미지 생성
      const reader = new FileReader();
      reader.onload = () => setPreviewImage(reader.result as string);
      reader.readAsDataURL(compressedFile);

      // 파일 입력 필드 초기화
      e.target.value = '';
    } catch (error) {
      alert('이미지를 처리하는 도중 오류가 발생했습니다. 다시 시도해 주세요.');
    }
  };

개선된 점

  • 서버에서 5MB 제한을 지정해줌 → 사용자에게 명확한 피드백 제공
  • 최대 크기 0.2MB로 압축 → 게시글 권장 크기(100~200KB) 준수
  • 최대 너비 또는 높이 1224px 제한
  • 압축 후 Blob → File 변환
    • 서버 업로드를 위한 일관된 파일 형식 유지

1224px 결정 이유

업로드된 이미지가 다양한 페이지에서 사용되는데,

가장 작은 사이즈에 맞추면 다른 뷰에서 이미지가 깨질 위험이 있었습니다.

그래서 여러 화면에서 가장 무난하고 균형 잡힌 크기로 보이도록 1224px로 지정했습니다.

결과

같은 이미지를 개선 전·후 적용해본 결과, 파일 크기는 4.3MB → 145KB, 로딩 시간은 1.01초 → 820ms로 개선되었습니다. 이로 인해 페이지 로딩 속도 향상, 사용자 경험 개선을 향상 시켰습니다.

라이브러리
https://www.npmjs.com/package/browser-image-compression
더 자세한 코드는 깃허브 참고
https://github.com/Co-Drive/Driver-Client/pull/369

profile
안녕하세요:)

0개의 댓글