React 프로젝트에 이미지를 사이즈 생각 안하고 넣었더니 로드하는 데 시간이 오래 걸려 이미지 사이즈를 최적화했다.

이미지 사이즈 줄이기

이미지 크기가 너무 크면 로드하는 데 시간이 걸리고 이미지 크기가 너무 작다면 화질이 저하된다. 그렇다면 이미지는 어느 정도 크기여야 적당할까?

나는 다음 말에 설득되어 이미지가 화면에서 차지하는 픽셀의 두 배 정도 크기로 이미지 사이즈를 조절했다.

단순히 화면에 표시되는 사이즈로 만들어야 한다고 생각할 수 있습니다. 물론 틀린 말은 아닙니다. 하지만 요즘 사용되는 레티나 디스플레이는 같은 공간(픽셀)에 더 많은 픽셀을 그릴 수 있기 때문에, 너비 기준으로 두 배 정도 큰 이미지를 사용하는 것이 적절합니다.
- 프론트엔드 성능 최적화 가이드, 유동근 지음

화면에서 최대 너비 384px, 높이 240px로 표시되는 이미지라면 원본 이미지 사이즈를 너비 768px, 높이 480px 정도 되도록 줄였다.
이미지 화질이 그렇게 중요하지 않은 프로젝트라서 그런지 화면 표시 픽셀 기준 두 배 크기로 줄여도 크게 달라 보이지 않았다.

이렇게 이미지 사이즈를 줄인 결과, 프로젝트에 사용된 총 34개의 이미지 파일 크기는 14.3MB에서 4.9MB로 줄었다.

JPG, PNG 대신 WebP 사용하기

사용된 이미지의 포맷이 JPG, 혹은 PNG라면 WebP를 사용해 파일 크기를 더 줄일 수 있다.

WebP는 구글에서 개발한 이미지 포맷으로, 손실 압축과 비손실 압축을 모두 제공하는 최신 이미지 포맷이다. 이미지 품질이 같을 때 파일 크기가 JPG와 PNG에 비해 훨씬 작다.

이미지 포맷 비교

  • JPG: 손실 압축, 그 만큼 작은 사이즈
  • PNG: 비손실 압축, 그 만큼 큰 사이즈
  • WebP: 손실 압축 & 비손실 압축, 작은 사이즈, 하지만 호환성 문제 존재
비교
사이즈 PNG > JPG > WebP
화질 PNG = WebP > JPG
호환성 PNG = JPG > WebP

이미지 포맷을 JPG, PNG에서 WebP로 변환해 총 34개의 이미지 파일 크기를 4.9MB에서 1.1MB로 감소시켰다.

picture 태그를 사용해 다양한 포맷의 이미지 제공하기

WebP는 압축 효율이 높아 가장 작은 사이즈로 이미지를 제공할 수 있지만 최신 이미지 포맷인 만큼 호환성 문제가 있다.
그래서 WebP를 지원하는 브라우저는 WebP 이미지를, WebP를 지원하지 않는 브라우저는 JPG나 PNG 이미지를 제공하도록 해줘야 한다.

picture 태그를 사용하면 다양한 포맷의 이미지를 제공할 수 있다.
브라우저는 source 요소 중 사용할 수 있는 요소가 있다면 사용하고 만약 사용할 수 없거나 브라우저가 picture 요소를 지원하지 않는다면 img 요소를 사용한다.
이걸 이용해 WebP를 지원하는 브라우저는 WebP 이미지를, WebP 이미지를 지원하지 않는 브라우저는 JPG나 PNG 이미지를 보여주도록 했다.

export default function Picture({ imgSrc }) {
  // ...
  return (
    <picture>
      <source srcSet={`${ImgSrc}.webp`} type="image/webp" />
      <img src={`${ImgSrc}.jpg`} alt={name} />
    </picture>
  );
}

참고로 picture 요소 안에 img 요소가 없으면 source 요소가 몇 개 있든 아무것도 표시되지 않는다.
이미지에 스타일이나 기타 속성을 설정하고 싶으면 img 요소에 설정해야 한다.

최적화 결과 비교

프로젝트에 사용된 총 34개의 이미지 파일을 최적화하면서 크기가 얼마나 감소했는지 비교해봤다.

파일 크기 기존에 비해 감소한 비율
기존 14.3MB -
사이즈 감소 4.9MB 66%
WebP로 변환 1.1MB 92%

최적화를 통해 이미지 크기가 최대 92% 감소했다!
실제로 웹사이트를 작동시켜 봤을 때도 이미지가 최적화 전보다 훨씬 빠르게 로드되었다.

해당 Pull Request를 통해 프로젝트에서 어떻게 이미지 사이즈 최적화했는지 확인할 수 있다.


참고

  • 프론트엔드 성능 최적화 가이드, 유동근 지음