본문 바로가기

optimization

[Webpack + Opt] 이미지 애셋 압축하기 (image-minimizer-webpack-plugin)

 

Intro.

load time 최적화를 달성하기 위해, 당연하지만 파일의 사이즈는 작을 수록 더 좋은 퍼포먼스를 보입니다. 그렇기에 image-minimizer-webpack-plugin 플러그인 패키지를 통해 빌드 시, 애셋을 압축할 수 있는 방법을 소개해보려합니다.. (  image-webpack-loader가 더이상 업데이트를 안한다고 하네요. )

 

 

Goal

 

Before

 

After

 

 

Method

 

해당 플러그인은 imagemin , squoosh , sharp , svgo 이렇게 4가지를 압축 알고리즘으로 추천하고 있고 별도로 커스텀 압축 알고리즘을 사용해도 되나, 이번 글에선 imagemin을 통해 구성해보겠습니다. 

 

각 애셋별 압축 알고리즘

  • png : pngquant
  • jpg,jpeg : mozjpeg
  • svg : svgo

를 사용했습니다.

 

 

 

1. 각 모듈들을 설치합니다.

yarn add -D image-minizer-webpack-plugin imagemin imagemin-pngquant imagemin-mozjpeg imagemin-svgo

 

2. 애셋 처리를 위해, 패턴 등록하기

 

빌드 후, 각 애셋들을 images 하위 경로에 놓이도록 filename을 아래와 같이 지정합니다. 

 

module.exports = {
	..., 'entry, output , plugins etc...'
    module: {
    rules: [
      ... , //다른 rule
      {
        test: /\.(png|jpg|svg|jpeg)$/,
        type: 'asset',
        generator: {
          filename: './images/[name].[contenthash:12][ext]'
        }
      }
}

 

3. 애셋들에 대해 최적화 처리를 할 수 있도록, config 객체의 optimization 프로퍼티에 image-minimizer-webpack-plugin을 등록합니다.

 

const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');

module.exports = {
	optimization : {
    	minimize: true,
        minimizer : [
        	'...', // <- 만약 production 환경과 develop환경이 나눠져있고, common config파일이 존재할 시, 좌측과 같이 명시함으로서, common config를 보전합니다.
            new ImageMinimizerPlugin({
            	minimizer : {
                	implementation: ImageMinimizerPlugin.imageminMinify, 
                    options: {
            			plugins: [
                        	['imagemin-mozjpeg', { quality: 40 }],
              			['imagemin-pngquant', { quality: [0.65, 0.9], speed: 4, strip: true }],
                            	[
                                'imagemin-svgo',
                                {
                                  plugins: [
                                    {
                                  name: 'preset-default'
                                  params: {
                                    overrides: {
                                      removeViewBox: false,
                                      addAttributesToSVGElement: {
                                        params: {
                                          attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }]
                                        	}
                          				}
                        			}
                      			 }
                    			}
                  			]
                		}
              		]
                        ]
                    }
                }
            })
            
        ]
    },
    module: {
        rules: [
          ... , //다른 rule
          {
            test: /\.(png|jpg|svg|jpeg)$/,
            type: 'asset',
            generator: {
              filename: './images/[name].[contenthash:12][ext]'
            }
    }
}

 

 

mozjpeg나 pngquant는 위에 쓰인 속성을 제외하고는 일반적인 상황에선 잘 사용안할듯 싶으나, 

 

svgo에 디폴트 플러그인으로 쓰인 'preset-default'에 꽤많은 피쳐들이 적용이 되있는데, 개발하다가 특정 피쳐가 제 svg를 이상하게 수정해놔서, 봤더니 기본값으로 제공된 피쳐중 하나랑 충돌하더군요.. 사용하신다면, 주의깊게 살펴보시는걸 추천합니다.

 

 

 

 

 

4. 용량이 작은 파일들에 대해선 그냥 base64 인코딩하여 인라인으로 주입하는게 더 효율적입니다. 저같은 경우, 5kb미만이면 그냥 인라인 형태로 이미지를 주입하겠습니다.

 

module: {
        rules: [
          ... , //다른 rule
          {
            test: /\.(png|jpg|svg|jpeg)$/,
            type: 'asset',
            parser: {
            	dataUrlCondition: {
                    maxSize: 5 * 1024 // 5 kb
                  }
            },
            generator: {
              filename: './images/[name].[contenthash:12][ext]'
            }
    }

 

 

 

 

'optimization' 카테고리의 다른 글

[Webpack + Opt] Code splitting (코드 스플릿팅)  (2) 2023.05.05
[Webpack + opt] css 최적화  (0) 2023.04.25