Imagemin을 사용하여 이미지 압축

Katie Hempenius
Katie Hempenius

왜 관심을 가져야 할까요?

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

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

도시의 스톡 이미지

20 KB

동일한 도시 풍경의 스톡 이미지로, 아티팩트와 흐림이 추가되었습니다.

12 KB

측정

Lighthouse를 실행하여 이미지를 압축하여 페이지 로드를 개선할 수 있는 기회를 확인합니다. 이러한 기회는 '이미지 효율적으로 인코딩' 아래에 나열됩니다.

'효율적으로 이미지 인코딩' 항목이 강조 표시된 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을 사용하려면 선택한 번들러에 사용 가능한 플러그인이 있는지 확인하세요. 예를 들어 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);
})();