React 이미지 최적화 후 업로드하기 (resize)

지인혁·2024년 5월 9일
2
post-thumbnail

문제 발견

지난 최적화에는 정적인 이미지 요소들만 최적화를 했습니다. 하지만 사용자가 업로드하고 서버에서 받아오는 이미지는 최적화가 되지 않았습니다.

저는 이미지 로드 시 뚝뚝 끊겨서 로딩되는 현상을 발견했습니다. STYLED라는 프로젝트에서는 이미지 콘텐츠가 많은 비중을 차지하고 있었고 사용자 경험 개선을 위해 원인을 찾아봤습니다.

딜레이가 있는 이미지들의 특징이 많은 용량을 차지하고 있어서 용량이 클수록 이미지 로드가 늦어지는 점을 발견했습니다.

해결 과정

우선 이미지를 업로드 할 때 사이즈를 줄여 용량을 줄이는 것이 첫 목표였습니다. 그리고 기존 jpg, png 등 포맷 방식에서 webP 형식을 선택함으로 더 최적화된 압축 방법을 선택했습니다.

react-image-file-resizer

이미지 업로드 시 리사이징과 포맷을 위해 react-image-file-resizer 라이브러리를 사용했습니다.

npm i react-image-file-resizer

해당 패키지를 설치 후 재사용 할 수 있게 유틸 함수로 구현했습니다.

import FileResizer from 'react-image-file-resizer';

type ResizeImage = (
  imageFile: File,
  width: number,
  height: number,
  quality?: number,
) => Promise<Blob>;

const resizeImage: ResizeImage = async (
  imageFile,
  width,
  height,
  quality = 100,
) => {
  return new Promise<Blob>((resolve, reject) => {
    FileResizer.imageFileResizer(
      imageFile,
      width,
      height,
      'WEBP',
      quality,
      0,
      (url) => {
        if (url instanceof Blob) {
          resolve(url);
        } else {
          reject(new Error('Result is not a Blob.'));
        }
      },
      'blob',
    );
  });
};

export default resizeImage;

그리고 이미지 업로드가 동작하는 API 호출하기 전 image 파일을 리사이징 했습니다.

export const updateProfileImage = async (image: File) => {
  try {
    const resizedImage = await resizeImage(image, 100, 100);
    const formData = new FormData();
    formData.append('isCover', 'false');
    formData.append('image', resizedImage);

    const res = await axiosAuthInstance.post<UserType>(
      DOMAIN.UPLOAD_PHOTO,
      formData,
    );

    return res.data;
  } catch (e) {
    handleError(e);
    return null;
  }
};

성과

기존 업로드 된 이미지 대신 새로운 이미지로 테스트 해봤습니다.

우선 프로젝트 크기에 맞게 사이즈를 변경하여 이미지 용량이 470kB에서 143kB로 개선되었습니다. 그리고 파일 형식도 jpg에서 webp 형식을 통해 더 높은 최적화가 되었습니다.

동일 네트워크 기준으로 이미지 로드 시간도 56ms에서 24ms로 거의 약 50% 개선되어 더 빠른 이미지를 로드할 수 있었습니다.

만약 서버에서 이미지 사이징을 지원해준다면 picture태그를 같이 사용하여 현재 화면에 맞게 더 작은 이미지를 요청하여 더욱 더 빠른 이미지 로드를 할 수 있습니다.

문제점

더 작은 용량을 욕심내다가... 만약 렌더링 사이즈보다 실제 이미지 사이즈가 작을 때 작은 이미지에서 큰 이미지로 늘어나기 때문에 화질이 깨지는 문제가 발생했습니다.

만약 해당 프로젝트처럼 서버에서 리사이징을 지원할 수 없는 상황이라면 큰 사이즈에서 작은 사이즈로 줄어드는 경우는 상관 없기때문에 해당 이미지가 사용되는 최대 크기 기준으로 넉넉히 리사이징하는 것을 추천합니다.

profile
대구 사나이

0개의 댓글