[최적화] imagemin으로 이미지 압축 자동화 하기

hsecode·2023년 6월 2일
5

최적화

목록 보기
5/7
post-thumbnail
post-custom-banner


📌 기본 사항

📎 node.js / npm 설치

기본적으로 node js와 npm 설치가 필요하다.

node js

npm install

📎 package json 생성

npm init -y

💡 -y : default 값으로 설정된 package.json 추가

📌 imagemin 설치하기

npm install imagemin

📌 imagemin-sharp 설치하기

npm install imagemin-sharp --save

📌 이미지 압축 js 파일 만들기

imagemin을 실행할 js파일을 제작한다.

import imagemin from 'imagemin';
import imageminSharp from 'imagemin-sharp';

const MAX_SIZE = 1920; // 이미지 최대 width 사이즈

async function optimizeImages(folderName) {
  const inputPath = 'imgs/*.{jpg,png}'; // 이미지 압축을 진행할 폴더 경로
  const outputPath = 'optimized'; // 압축된 이미지를 저장할 폴더 경로

  const files = await imagemin([inputPath], {
    destination: outputPath,
    plugins: [
      imageminSharp({
        chainSharp: async (sharp) => {
          const meta = await sharp.metadata();
          if (meta.width > MAX_SIZE) {
            return sharp.resize({ width: MAX_SIZE }); // 이미지의 width 값이 1920px 보다 클 경우 1920px로 조정
          }
          return sharp;
        },
      }),
    ],
  });

  console.log('✨ Image optimize COMPLETE ✨');
}

⭐️ 개선하기

위와 같이 작성했을 때 몇가지 문제가 있었다.

  1. 실제 업무 환경에서 이미지 경로를 다시 일일이 변경해주기 어려운 부분이 있음
    ➡️ input과 output의 경로를 동일하게 지정해 이미지를 덮어쓰기 한다.

  2. 프로젝트별로 이미지 폴더를 관리할 경우 일일이 경로를 변경해야해서 번거롭다.
    ➡️ build 명령어에 폴더명을 쓰면 해당 폴더의 이미지가 최적화되도록 한다.

  3. MAX_SIZE 값을 넘는 이미지를 임의로 조정할 경우 실제 운영 화면에 영향이 있을 수 있음
    ➡️ 리사이징 없이 원본 사이즈대로 최적화하며, MAX_SIZE를 넘는 이미지일 경우 주의 문구를 띄워준다.

몇번의 과정을 거쳐 아래 코드로 개선했다.

import imagemin from 'imagemin';
import imageminSharp from 'imagemin-sharp';

const MAX_SIZE = 5000;

async function optimizeImages(folderName) {
  const INPUT = `imgs/${folderName}/*.{jpg,png}`;
  const OUTPUT = `imgs/${folderName}`;

  const files = await imagemin([INPUT], {
    destination: OUTPUT,
    plugins: [
      imageminSharp({
        chainSharp: async (sharp) => {
          const meta = await sharp.metadata();
          if (meta.width > MAX_SIZE) {
            console.warn(`🚨 주의 : width 값이 ${MAX_SIZE}px을 초과하는 이미지가 있습니다.`);
            return sharp;
          }
          return sharp;
        },
      }),
    ],
  });

  console.log(`${folderName} 의 이미지 압축이 완료되었습니다. ✨`);
}

if (process.argv.length >= 3) {
  const folderName = process.argv[2];
  optimizeImages(folderName).catch((error) => {
    console.error(`Error optimizing images for ${folderName}:`, error);
  });
} else {
  console.error('Error: Please provide the folder name as an argument.');
}

📌 package.json 수정

코드 작성이 완료되었으면 package.json에 실행 명령어와 패키지를 추가한다.

{  
  "scripts": { // 실행 명령어
    "imgbuild" : "node imgbuild.js" 
  },
  "dependencies": { // 패키지 추가
    "imagemin": "^8.0.1",
    "imagemin-sharp": "^1.0.6"
  }
}

🚨 Warning: To load an ES module 에러가 뜰 경우

node.js에서 ES모듈을 사용하면서 발생된 에러.

📎 가장 간단한 방법

package.json에 type module 을 추가한다.

{
 ...
 
  "type": "module", // 이 부분을 추가
  "scripts": {
    "imgopt" : "node imgopt.js"
  },
  "dependencies": {
    "imagemin": "^8.0.1",
    "imagemin-sharp": "^1.0.6"
  }
}

📎 기존 개발환경과 충돌해 type module을 추가할 수 없을 경우

commonJS 방식으로 코드를 다시 작성하거나, 파일의 확장자를 .mjs로 변경한다.
확장자를 .mjs로 변경하기로하고, package.json에서 실행 명령어 부분도 함께 수정한다.

{
 ...
  "scripts": {
    "imgopt" : "node imgopt.mjs"
  },
  "dependencies": {
    "imagemin": "^8.0.1",
    "imagemin-sharp": "^1.0.6"
  }
}

📌 실행

npm run imgopt imgopt_test

각자 지정해둔 명령어를 실행하면 이미지 압축 완료!

🚧 주의

  • MAX_SIZE를 넘어가는 이미지는 해당 사이즈가 최선인지, 불필요하게 큰 이미지를 사용한 것이 아닌지 확인한다.
  • 한번 최적화 된 이미지는 다시 최적화 빌드를 돌려도 더이상 용량이 줄어들지 않습니다.

👏🏻 마무리

🐱: 이미지는 생각보다 많은 용량을 차지하는 부분이다. 이미지를 태산 모아 티끌처럼 압축해서 최적화에 기여하자 !

🗂 참조한 문서

profile
Markup Developer 💫
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 6월 2일

디자인팀에서 전달해 준 이미지들이 가끔 용량이 너무 커서 포토샵 혹은.. 웹 툴을 이용해서 퀄리티를 낮추곤 했는데요!
이렇게 하면 폴더별로 용량 압축을 진행할 수도 있어 효과적으로 사용할 수 있을 것 같네요.

좋은 자료 공유 감사합니다!

1개의 답글