Imagemin을 사용하여 이미지 압축

Katie Hempenius
Katie Hempenius

왜 관심을 가져야 할까요?

비압축 이미지는 불필요한 바이트로 페이지를 부풀립니다. 이미지는 최대 콘텐츠 페인트 (LCP)의 후보가 될 수 있으므로 이러한 불필요한 바이트를 사용하면 이미지의 리소스 로드 시간이 늘어나 LCP 시간이 길어질 수 있습니다.

오른쪽 사진은 왼쪽 사진보다 40% 작지만 일반 사용자에게는 동일하게 보일 수 있습니다.

20 KB

12 KB

측정

Lighthouse를 실행하여 이미지를 압축하여 페이지 로드를 개선할 수 있는 기회가 있는지 확인합니다. 다음과 같은 기회는 '이미지를 효율적으로 인코딩' 아래에 표시됩니다.

이미지

Imagemin

Imagemin은 다양한 이미지 형식을 지원하고 빌드 스크립트 및 빌드 도구와 쉽게 통합할 수 있으므로 이미지 압축에 적합합니다. Imagemin은 CLInpm 모듈로 모두 사용할 수 있습니다. 일반적으로 npm 모듈은 더 많은 구성 옵션을 제공하므로 가장 좋지만, 코드를 건드리지 않고 Imagemin을 사용해 보려는 경우 CLI가 적절한 대안이 될 수 있습니다.

플러그인

Imagemin은 '플러그인'을 중심으로 빌드됩니다. 플러그인은 특정 이미지 형식을 압축하는 npm 패키지입니다 (예: 'mozjpeg'는 JPEG를 압축함). 인기 있는 이미지 형식에는 선택할 수 있는 여러 플러그인이 있을 수 있습니다.

플러그인을 선택할 때 가장 중요한 것은 '손실이 있는' 플러그인인지 '손실이 없는' 플러그인인지 여부입니다. 무손실 압축에서는 데이터가 손실되지 않습니다. 손실 압축은 파일 크기를 줄이지만 이미지 품질이 저하될 수 있습니다. 플러그인이 '손실이 있는'지 '손실이 없는'지 언급하지 않는 경우 API를 통해 알 수 있습니다. 출력의 이미지 품질을 지정할 수 있으면 '손실이 있는' 것입니다.

대부분의 사용자에게는 손실이 있는 플러그인이 가장 좋습니다. 훨씬 더 큰 파일 크기 절감 효과를 제공하며 필요에 따라 압축 수준을 맞춤설정할 수 있습니다. 아래 표에는 널리 사용되는 Imagemin 플러그인이 나와 있습니다. 이 외에도 사용할 수 있는 플러그인이 있지만 이 플러그인이 모두 프로젝트에 적합합니다.

Imagemin CLI

Imagemin CLI는 imagemin-gifsicle, imagemin-jpegtran, imagemin-optipng, imagemin-pngquant, imagemin-svgo라는 5가지 플러그인과 함께 작동합니다. Imagemin은 입력의 이미지 형식을 기반으로 적절한 플러그인을 사용합니다.

'images/' 디렉터리의 이미지를 압축하여 동일한 디렉터리에 저장하려면 다음 명령어를 실행합니다 (원본 파일이 덮어쓰기됨).

$ imagemin images/* --out-dir=images

Imagemin npm 모듈

번들러와 함께 Imagemin을 사용하려면 선택한 번들러에 Imagemin용 플러그인이 있는지 확인하세요. 예를 들어 webpack은 Imagemin을 효과적으로 지원하는 인기 있는 번들러입니다. 이 Codelab에서 webpack과 함께 Imagemin을 사용하는 방법을 자세히 알아보세요.

Imagemin을 단독으로 Node 스크립트로 사용할 수도 있습니다. 이 코드는 'imagemin-mozjpeg' 플러그인을 사용하여 JPEG 파일을 품질 50 ('0'이 가장 나쁘고 '100'이 가장 좋음)으로 압축합니다.

const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');

(async() => {
  const files = await imagemin(
      ['source_dir/*.jpg', 'another_dir/*.jpg'],
      {
        destination: 'destination_dir',
        plugins: [imageminMozjpeg({quality: 50})]
      }
  );
  console.log(files);
})();