Don’t worry about failures

웹펙 - 번들사이즈 줄이기 본문

카테고리 없음

웹펙 - 번들사이즈 줄이기

허흥 2024. 3. 12. 12:40
728x90

웹펙의 옵션들을 통해 번들 사이즈를 최적화를 하고자한다. 

 

1. Webpack mode

1-1 none

  • 모드를 설정하지 않은 경우에는 웹팩의 기본 동작에 따라 동작.
  • 개발 모드나 프로덕션 모드와는 달리 추가적인 최적화나 디버깅 정보를 포함하지 않는다.

1-2. Development

개발에 초점이 맞춰져 있다. 

  • 코드 최적화 작업이 이루어지지 않음. 디버깅에 도움되는 추가 정보를 번들에 포함.
  • 소스맵을 생성하여 원본 코드와 번들된 코드 간의 매핑을 제공하여 디버깅에 용이함.
  • 빠른 빌드 시간을 위해 코드 최적화를 최소화하고, 개발자 경험을 향상시키기 위해 빌드된 번들에 추가 정보 포함.

1-3 Production

  • 코드를 최적화하고 번들 파일 크기를 최소화하여 빠른 성능을 제공한다.
  • 불필요한 주석이나 공백 등의 코드를 제거, 코드 난독화 수행한다.
  • 소스맵 제거하여 빌드된 번들 크기의 최소화한다.

 

위의 옵션을 기준으로 웹펙으로 빌드를 해보자.

1. none

 

2. development

 

3.production

 

3개의 모드에 대해 살펴본 결과를 살펴보면,

확연하게 production환경에서 사이즈가 줄어든 것을 확인할 수 있다. 6키로바이트에서 728바이트 단위까지 많이 줄어든다.

내부 코드를 확인했을 때도, 주석 등 제거되는 것도 확인이 되었다.

 

none과 development를 비교해봤을 때는 사이즈 측면에서 봤을 때는 오히려 development가 더 크다. 그 이유는 디버깅을 위해 소스맵에 따라 원본 파일이 존재했기 때문이다. 

 

2. 소스맵

위에서 잠깐 나온 소스맵은 웹펙, 바벨 등에 의해서 생성이 될 수 있다. 이는 압축된 형태로 배포된 javascript 파일과 개발 중에 작성한 원본 소스 코드 간의 매핑 정보를 제공하는 파일. 매핑 정보를 통해 개발자는 압축되거나 변환된 코드를 디버깅할 때 원본 소스를 찾아볼 수 있다.

  • 디버깅 용이. 디버깅 시 원본 코드의 라인 및 열 정보를 제공.
  • 성능 최적화. 프로덕션 환경에서는 보통 소스맵을 제거하여 번들 크기를 줄이고, 어플리케이션의 성능을 향상.
  • 소스맵은 주로 빌드 도구(웹펙)에서 생성되며, 빌드 구성 옵션에서 활성화. 이렇게 생성된 소스맵은 브라우저의 개발자 도구에서 로드되어 디버깅 시 사용.
  • 소스맵은 Typescript, babel과 같은 트랜스 파일러에서도 생성될 수 있음.

devtool을 통해 sourceMap 설정을 할 수 있다.

  1. none: 소스맵을 생성하지 않는다. 디버깅을 위한 소스맵이 필요하지 않은 경우에 사용. 소스맵을 생성하지 않으므로 빌드된 파일의 크기가 가장 작다.
  2. eval: 각 모듈을 eval 함수로 감싸고 해당 모듈의 소스맵 정보를 데이터 URL로 포함합니다. 빌드 시간이 빠르지만, 디버깅 품질은 낮을 수 있다.
  3. cheap-eval-source-map: 번들된 코드를 eval 함수로 감싸고, 컬럼 번호(column number) 없이 번들된 코드와 소스 파일을 매핑합니다. 번들 크기는 빠르고 디버깅은 상대적으로 빠르다.
  4. cheap-source-map: 소스맵에서 컬럼(column) 정보를 생략하여 번들된 코드와 소스 파일을 매핑한다. 번들 크기는 더 크지만, 디버깅 품질이 좋다.
  5. eval-source-map: 각 모듈을 eval 함수로 감싸고 소스맵을 별도의 파일로 생성한다. 디버깅 품질이 높으나 빌드 시간이 조금 더 걸릴 수 있다.
  6. cheap-module-eval-source-map: cheap-eval-source-map과 유사하지만, 모듈 간에 원시 소스 파일의 경로를 제공한다.
  7. cheap-module-source-map: cheap-source-map과 유사하지만, 모듈 간에 원시 소스 파일의 경로를 제공한다.
  8. source-map: 소스맵을 별도의 파일로 생성하고 모든 소스 코드와 소스맵 정보를 포함. 가장 높은 품질의 디버깅을 제공하지만, 빌드 시간과 번들 크기가 늘어난다.

devtool의 기본값은 mode에 따라 다르다.

development => devtool : eval

production => devtool : none

 

2.  Code Splitting

애플리케이션의 코드를 여러 개의 작은 청크로 나누어 빌드하는 기술. 코드 분할을 사용하면 어플리케이션을 효율적으로 로드할 수 있으며, 초기 로드 시간을 줄이고 페이지 성능을 개선할 수 있다.

 

주요 분할 방법 및 사용

 

1. 동적 코드 분할 

어플리케이션의 특정 부분이나 요청에 따라 코드를 동적으로 로드하는 기술.

방법1. import()함수 사용. 동적 코드분할 가장 일반적인 방법. 이 함수는 Promise를 반환.

import('./module').then(module => {
	//load된 모듈 사용
});

방법2. 웹펙 설정에서 설정. 

module.exports = {
    // ...
    optimization: {
        splitChunks: {
            chunks: 'all', // 모든 종류의 청크에 대해 공통 모듈을 추출
        },
    },
};

 

2. Entry Points로 코드 분할

어플리케이션의 여러 진입점(entry point)을 정의하여 각 진입점에 해당하는 코드를 분리하는 기술.

 

2-1. 웹펙 설정에서 Entry Points 정의.

module.exports = {
    entry: {
        main: './src/index.js',
        admin: './src/admin.js',
    },
    // ...
};

웹팩은 위에서 정의된 진입점에 따라 각각의 번들을 생성한다.

dist/
├── main.bundle.js
└── admin.bundle.js

 

2-2 적절한 곳에서 동적으로 로드.

각각의 진입점에 해당하는 번들을 적절한 곳에서 동적으로 로드.

import('./admin.bundle.js').then(admin => {
    // 'admin' 번들을 로드하고 로드된 모듈을 사용합니다.
});

 

3. SplitChunks 플러그인

중복된 코드를 감지하고 공통 모듈을 별도의 청크로 분리하여 번들을 최적화하는 기능을 제공한다.이를 통해 불필요한 코드의 중복을 줄이고 애플리케이션의 초기 로드 시간을 최소화 할 수 있다.

 

주요 특징

1. 공통 모듈 추출 : SplitChunks 플러그인은 번들링된 여러 모듈 중에서 공통된 부분을 식별하고 이를 별도의 청크로 분리. 이를 통해 공통 모듈을 한 번만 로드하여 캐싱하고 다른 페이지에서 재사용할 수 있음.

2. 웹팩 설정에서 사용 : SplitChunks 플러그인은 웹팩 설정 파일에서 사용. optimization.splitChunks 옵션을 통해 SplitChunks 플러그인을 활성화하고 최적화 옵션을 설정할 수 있음.

3. 다양한 설정

module.exports = {
    // ...
    optimization: {
        splitChunks: {
            chunks: 'all',
            minSize: 30000,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        },
    },
};
728x90