Webpack 3에서 Code Splitting 최적화한 경험
문제 상황
사내 어드민 페이지의 번들 사이즈가 2.3MB까지 커지면서 초기 로딩에 7~8초가 걸리는 상황이 발생했다. 특히 네트워크가 느린 환경에서는 사용이 거의 불가능한 수준이었다.
해결 과정
1. 번들 분석
webpack-bundle-analyzer를 설치해 번들 구성을 확인했다.
npm install --save-dev webpack-bundle-analyzer
moment.js의 locale 파일들과 lodash 전체가 포함되어 있었고, 차트 라이브러리도 모든 페이지에서 로드되고 있었다.
2. CommonsChunkPlugin 설정
module.exports = {
entry: {
app: './src/index.js',
vendor: ['react', 'react-dom', 'redux', 'react-redux']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
})
]
};
3. Dynamic Import 적용
차트 페이지처럼 특정 라우트에서만 사용하는 무거운 라이브러리는 동적 임포트로 분리했다.
// Before
import ChartComponent from './components/Chart';
// After
const ChartComponent = () => import('./components/Chart');
4. Moment.js locale 제거
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
결과
- 초기 번들: 2.3MB → 680KB
- 초기 로딩 시간: 7.8초 → 4.2초
- vendor 번들 캐싱으로 재방문 시 로딩 시간 대폭 감소
배운 점
Webpack 3의 CommonsChunkPlugin은 설정이 직관적이지 않아 문서를 여러 번 읽어야 했다. 특히 manifest 청크를 별도로 분리하지 않으면 vendor 해시가 앱 코드 변경 시마다 바뀌어 캐싱 효과가 사라진다는 점을 뒤늦게 알았다. 다음에는 초기부터 번들 사이즈를 모니터링하는 게 중요하겠다.