Webpack은 css,js,file 등을 하나의 파일로 만드는 만큼 용량이 클 수 밖에 없습니다.
아래 그림은 처음 Herelux 베타버전을 Vue로 웹 프론트엔드를 개발할 당시 겪은 bundle.js의 파일 크기 입니다.
무려….5.27MB 입니다.
이러면 웹 페이지를 접속할때마다 5.27MB 를 다운받고 있는 것입니다.
실제로 페이지로딩이 체감상 느렸습니다. 트래픽이라도 늘어나면 매우비효율적이죠.
어떻게 줄일 수 있을까요?? 먼저 bundle.js 을 분석하면서 많이 잡아먹는 라이브러리를 분석해야 합니다.
UglifyJs
코드 스플리팅 syntax-dynamic-import
webpack bundle.js의 파일 분석하기.
npm i webpack-bundle-analyzer
webpack.config.js에 추가
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports.plugins = (module.exports.plugins || []).concat([
{...},
new BundleAnalyzerPlugin() //이걸 추가해 주세요.
])
추가한 뒤에 아래 명령어로 실행시킵니다.
npm run dev
이 http://127.0.0.1:8888/ 주소로 접속하게 되면 아래 그림과 같이 bundle.js 구성요소들을 보여줍니다.
node_module 과 src 부분으로 나누어집니다. node_module은 라이브러리를 나타내고 src는 scss와 vue,js파일들을 보여줍니다.
webpack-bundle-analyzer는 이처럼 높은 bundle.js에 내가 불필요한 모듈을 사용하고 있는 건 아닌지, 또는 과도한 용량을 잡아먹고있는 모듈을 볼 수 있습니다.
첫번째 방식에서 더이상 줄일 수 있는 모듈이 없다면, UglifyJs를 사용합니다. Webpack 포스팅에서도 설명했지만 UglifyJs는 코드를 난독화 하는 방식으로 길고 긴 코드의 양을 난독화 시켜 엄청나게 축소시키는 방식을 말합니다.
정말 어마어마한 효과를 가지고 있습니다.
Webpack4는 그래서 기본적으로 UglifyJs가 내장되어있어요.
webpack.config.js plugin부분
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
5.27MB 에서 860kb 로 줄어든걸 확인할 수 있습니다. 무려 5배가량이 줄었습니다.
보통 Vue나 React 프레임웍으로 개발하게 되면 각 화면, 기능별로 템플릿을 나누어서 개발하게 됩니다.
SPA(Single Page Application)의 특징상 많은 파일들이 생성될 수 밖에 없습니다. 하지만 bundle.js의 용량만 늘어나게 되죠.
babel은 자바스크립트의 문법에 구속되지 않게 개발할 수 있게 하는 하나의 모듈입니다.(ex:ES5, ES6)
bable에 syntax-dynamic-import을 추가하게 되면 문법에 구속되지 않게 되죠.
npm install –save-dev @babel/plugin-syntax-dynamic-import
설치가 완료되면 .babelrc 파일에 아래코드를 작성합니다.
.babelrc
{
"presets": [
["env", { "modules": false }],
"stage-3"
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
],
["syntax-dynamic-import"]
]
}
Vue는 지연된 로딩이라는 코드분할을 권유하고 있습니다.
간단하게 설명하자면 각 컴포넌트마다 비동기 모듈로 호출하게 되서 bundle.js에 용량이 확 줄어들게 되죠.
아래와 같은 방식으로 코드분할 하시면됩니다.
import Event from '../components/Event.vue'
Vue.use(Router)
//Named Vue
const router = new Router({
mode:'history',
routes:[
{
path: '/',
name: 'Event'
}
]
})
const Event = () => import('../components/Event.vue'); //코드분할하는 방식의 선언입니다.
Vue.use(Router)
//Named Vue
const router = new Router({
mode:'history',
routes:[
{
path: '/',
name: 'Event'
}
]
})