Webpack 3에서 번들 사이즈 최적화하기
문제 상황
회사 대시보드 프로젝트의 프로덕션 빌드 결과물이 2.3MB에 달했다. 3G 환경에서 초기 로딩에 10초 이상 걸리는 상황이었고, 모바일 사용자 이탈률이 눈에 띄게 증가했다.
분석
webpack-bundle-analyzer를 사용해 번들 구성을 분석했다.
npm install --save-dev webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
};
결과, moment.js의 locale 파일들(600KB), lodash 전체(500KB), 그리고 사용하지 않는 라이브러리 코드들이 대부분을 차지하고 있었다.
해결 방법
1. Dynamic Import로 코드 스플리팅
라우트별로 청크를 분리했다.
const Dashboard = () => import('./pages/Dashboard');
const Settings = () => import('./pages/Settings');
const routes = [
{ path: '/dashboard', component: Dashboard },
{ path: '/settings', component: Settings }
];
2. Moment.js locale 제거
한국어만 사용하므로 나머지 locale은 제외했다.
const webpack = require('webpack');
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
3. Lodash 최적화
lodash-webpack-plugin을 사용해 불필요한 기능을 제거했다.
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
plugins: [
new LodashModuleReplacementPlugin()
]
4. UglifyJS 옵션 조정
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console: true,
warnings: false
}
}
})
]
}
결과
- 초기 번들: 2.3MB → 980KB (57% 감소)
- 초기 로딩 시간: 10.2초 → 4.1초 (3G 기준)
- Lighthouse 성능 점수: 42 → 78
코드 스플리팅으로 첫 페이지 로딩에 필요한 코드만 불러오게 되었고, 나머지는 라우트 이동 시 lazy loading되도록 개선했다.
교훈
번들 사이즈 최적화는 지속적으로 모니터링해야 하는 작업이다. webpack-bundle-analyzer를 CI에 통합해 PR마다 번들 사이즈 변화를 체크하도록 설정했다. 외부 라이브러리 추가 시 번들 사이즈 영향을 먼저 확인하는 습관이 필요하다.