[webpack] terser-webpack-plugin 으로 번들 파일 압축하여 성능 최적화하기

BinaryWoo_dev·2023년 4월 25일
0

웹 성능

목록 보기
2/2
post-thumbnail

서론


최근에 회사 솔루션을 기반으로 몇몇 서비스 운영 사이트에 연동 되는 IoT 엔드 디바이스 개수들이 급격히 증가하면서 웹 애플리케이션 성능이 현저히 떨어져 현장 관리팀으로부터 Web 성능 개선 요청을 받았다.
여기에서 내가 유일한 프론트엔드 개발자이기 때문에 어떻게 성능을 측정할 것이며, 어떤 식으로 개선할 지 방향을 잡기 위해서 하루~이틀 정도 분석하고 알아본 결과로 아래와 같이 방향을 잡았다.

성능 측정 방법

  • Google에서 직접 개발하여 제공하는 lighthouse 로 웹의 전반적인 성능을 측정하기로 했다.

성능 개선 방안

  • API 호출 로직 개선
    - 불필요한 또는 중복되는 API 호출 로직
    • 동기적으로 호출되고 있는 API 호출 로직
    • 불필요한 데이터까지 모두 return 해주는 API 개선
  • 동적 임포트 사용 (nextjs 에서 제공하는 dynamic import 사용)
  • 코드 압축
  • 이미지 압축

이번 글에서는 코드 압축 솔루션에 대한 방법을 다뤄보고자 한다.

본론



먼저 압축하기 전 현재 번들 파일의 크기는 위와 같이 무려 9.23GB나 되는 것을 확인할 수 있었다.
(빌드 파일 크기를 자주 볼 일이 없었는데 이번 기회에 제대로 확인했다가 뒷목 잡을 뻔했다)

이제 차근차근 코드 압축을 위한 절차를 진행해보도록 하자.

의존성 패키지 설치

먼저 필요한 의존성 패키지들은 아래와 같다.

  • babel-preset-minify
  • babel-minify-webpack-plugin
  • terser-webpack-plugin
	$yarn add babel-preset-minify

여기서 terser-webpack-plugin은 현재 프로젝트에서 사용하는 webpack 번들러 버전에 맞춰서 설치해야한다. (우리 회사 프로젝트는 webpack4를 사용하고 있어서 4.2.3 버전을 설치하였다.)

  • webpack4 사용할 경우 : 4.0.0 <= terser-web-pack-plugin <= 4.x.x
  • webpack5 사용할 경우 : 5.0.0 <= terser-web-pack-plugin <= 5.x.x
	$yarn add -D babel-minify-webpack-plugin terser-webpack-plugin@4.2.3

환경 세팅

babel 환경 세팅

babel 환경설정 파일에서 presets 에 minify 프리셋을 아래와 같이 설정해준다.
(babel-preset-minify 상세 정보)

  • buildIns : 인스턴스 호출을 최소화해준다.

        // Input
        Math.floor(a) + Math.floor(b)  -> 
    
        // Output
        var _Mathfloor = Math.floor;
    
        _Mathfloor(a) + _Mathfloor(b);
  • evaluate : 계산식을 결과값 형태로 변환하거나 개량화하여 코드를 압축한다.

      // Input
          "a" + "b"
          2 * 3;
          4 | 3;
          "b" + a + "c" + "d" + g + z + "f" + "h" + "i"
    
      // Output
          "ab";
          6;
          7;
          "b" + a + "cd" + g + z + "fhi";
  • mangle : 변수명을 최소한의 문자열로 변형하여 코드를 압축한다.

      // Input
         var globalVariableName = 42;
          function foo() {
            var longLocalVariableName = 1;
            if (longLocalVariableName) {
              console.log(longLocalVariableName);
            }
          }
    
      // Output
          var globalVariableName = 42;
          function foo() {
            var a = 1;
            if (a) {
              console.log(a);
            }
          }

.babelrc

{
  "presets": [
    ["minify", { "builtIns": false, "evaluate": false, "mangle": false }]
  ],
 

webpack 환경세팅

회사 솔루션의 프로젝트에서는 webpack 환경설정 파일을 따로 두지 않고, nextjs 환경설정 파일(next.config.js) 에서 정의한다.

(terser-webpack-plugin 상세 정보)

next.config.js


module.exports = {
  	webpack5: false,
	webpack: (config) => {
      config.optimization = {
        ...config.optimization,
        minimize: true,
        minimizer: [
          new TerserPlugin({
            test: /\.(js|jsx|ts|tsx)$/,
            parallel: true,
            terserOptions: {
              format: {
                comments: false, // 빌드 시, comment 제거 (주석 제거)
              },
              compress: {
                drop_console: true, // 빌드 시, console.* 구문 코드 제거
              },
            },
            extractComments: false, // 주석을 별도의 파일로 추출할 지 여부
          }),
        ],
      };
    return config;
    }
};

빌드 진행

이제 전반적인 환경 설정은 완료되었으니 빌드를 진행해보도록 한다.

빌드 명령어

$yarn build

빌드 타임은 총 163.55s 가 걸렸다.
이제 빌드 번들 파일 크기를 확인해보도록 한다.

세상에🫢, 9.23GB -> 97.5MB 로 압축되었다.
무려 약 ✨90%✨ 에 달하는 압축률을 달성하였다.

결론


  • webpack 과 babel의 내장 기능과 플러그인들을 통해 번들 사이즈 압축을 하는 방법을 터득할 수 있었다.
  • 다음에는 nextjs 에서 제공하는 next/image 기능으로 이미지를 압축하여 좀 더 최적화시킬 수 있도록 시도해볼 것이다.
profile
매일 0.1%씩 성장하는 Junior Web Front-end Developer 💻🔥

0개의 댓글