DevOps/Optimization

이미지 최적화로 이미지 크기 75% 줄이기

닝닝깅 2024. 5. 28. 16:53

🚨 고민 발생

판매 상품 등록 시 이미지가 필수로 등록되어야 한다. 등록된 이미지는 firebase storage에 저장되고 storage url을 통해 이미지를 불러오게 된다.

 

전체 상품을 조회하는 페이지에서 다량의 상품 이미지를 불러오는데 이때 소요되는 로딩 시간이 너무 길어 사용자 경험이 떨어지는 문제가 발생한다.

 

📍 고민 해결 방법

크기가 작은 썸네일용 이미지를 만들자!

긴 로딩시간의 원인이 불필요하게 큰 이미지 크기라고 생각했고, 전체 상품 조회 페이지에서 보여질 크기가 작은 썸네일을 별도로 저장하는 방법을 선택했다. 

 

📍 이미지 최적화 과정

이미지 크기를 줄이기 위해서 두 가지 방법을 쓸 수 있었다.

1. 이미지 크기 압축

2. 이미지 포맷 변환

 

썸네일 크기에 맞는 수치로 이미지 크기를 압축하고, webp 포맷을 사용하여 이미지 품질이 떨어지지 않으면서도 크기 최적화가 가능하도록 계획하였다.

 

이미지 변환을 위한 라이브러리는 react-image-file-resizer과 pica 중 고민을 하였고,

번들 사이즈 용량이 더 작으면서 리액트와 좀 더 호환성이 좋은 react-image-file-resizer을 선택했다.

크기 압축과 포맷 변환을 한번에 할 수 있어 비교적 간단하게 사용할 수 있었다.

 

리사이징 프로미스를 반환하는 리사이징 함수를 만들고, 추후 비동기 처리를 통해 이미지 리사이징 후 업로드가 순서대로 진행되도록 했다.

const resizeFile = (file: File) =>
    new Promise((resolve) => {
        Resizer.imageFileResizer(
            file, // 리사이즈할 이미지 파일
            300, // 리사이즈된 새 이미지의 최대 너비
            300, // 리사이즈된 새 이미지의 최대 높이
            "WEBP", // 리사이즈된 새 이미지의 압축 형식
            100, // 리사이즈된 새 이미지의 품질
            0, // 업로드된 이미지에 적용할 시계 방향 회전 각도
            (uri) => {
                resolve(uri);
            }, // 리사이즈된 새 이미지 URI의 콜백 함수
            "file", // 리사이즈된 새 이미지의 출력 유형
            200, // 리사이즈된 새 이미지의 최소 너비
            200 // 리사이즈된 새 이미지의 최소 높이
        );
    });

 

 

📍 이미지 최적화 결과

리사이징한 이미지 크기가 원본 크기보다 최대 1/4로 줄어든 것을 확인했다.

 

 

그리고 가장 많은 썸네일이 사용되는 랜딩 페이지에서 리사이징 전후로 Lighthouse 검사를 진행했고, 경고문에서 확인할 수 있는 저장 공간 절약량이 리사이징 후에 90% 정도 줄어든 효과를 보았다.

 

 

+ 정적 리소스 이미지라면??

정적 리소스로 넣은 이미지의 경우 빌드 시 플러그인을 통하여 압축할 수 있다.

하지만 많은 이미지를 압축하는 경우에는 빌드 시간이 크게 지연되기 때문에 주의해야 한다.