Vue 번들 크기 줄이기

번들링 도구를 사용하여 자바스크립트를 번들링하는 경우, 모든 내용이 하나로 합쳐진 큰 파일이 생성되게 됩니다. 브라우저에서 하나의 큰 파일을 로딩하는 경우에는 많은 초기 로딩 시간이 소요될 수 있습니다.

아래에서는 자바스크립트 번들 크기를 줄이는 방법 몇 가지를 간략히 설명합니다. 이 글은 Vue + Webpack4 기준으로 작성하였으며, 부족하거나 자세한 내용은 링크된 글을 참고하시기 바랍니다.

코드 스플리팅(Code splitting)

코드를 분할하여 사용자가 원하는 시점에 파일을 로딩하여 애플리케이션 초기 로딩 속도를 개선하는 방법입니다. Vue는 컴포넌트 정의를 비동기 방식으로 처리할 수 있는 방법을 제공합니다.

아래와 같이 비동기로 로딩되는 컴포넌트를 작성할 수 있습니다.

Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
        resolve({
            template: '<div>I am async!</div>'
        })
    }, 1000)
})

이를 이용하여 Vue Router에서 라우팅시 컴포넌트를 로딩하도록 작성할 수 있습니다.

{
    path: 'url 이름',
    component: () => import('컴포넌트 이름')
}

Webpack에서 제공하는 webpackChunkName을 사용하면 리소스를 분리하고 묶을 수 있습니다. webpackChunkName 지정하면 해당 이름으로 파일이 분리되어 빌드됩니다.

const Home = () => import(/* webpackChunkName: "home" */ './Home.vue');
const About = () => import(/* webpackChunkName: "about" */ './About.vue');
const Contact = () => import(/* webpackChunkName: "contact" */ './Contact.vue');

참고

번들 최적화

webpack으로 명시적으로 분할된 번들(chunk)은 로딩할 때에 동일한 종속성을 다운받아 사용될 수 있습니다. 이러한 문제를 최적화하기 위해 webpack에서는 splitChunks 옵션을 제공합니다. 이 옵션은 여러 번들에서 공유되는 종속성을 별도로 그룹화 하여 재사용하도록 합니다.

// webpack.config.js
optimization: {
  splitChunks: {
    chunks: 'all'
  }
}

참고

트리-쉐이킹(Tree-shaking)

트리쉐이킹은 나무를 흔들어서 필요없는 것을 떨어트리는 행위를 은유적으로 풀어낸 표현입니다. 기술적으로는 번들링 과정에서 사용하지 않는 코드를 제거하고 파일크기를 줄여서 로딩 성능을 향상시키는 방법입니다.
webpack4에서는 ES6 모듈(import, export)을 대상으로 tree-shaking이 기본으로 동작합니다. 하지만, CommonJS 방식의 모듈(require)을 사용하는 경우에는 동작하지 않습니다.

lodash를 예로 들면, lodash는 CommonJS 형태로 번들링되어 배포되기 때문에 webpack의 기본설정으로는 lodash를 트리쉐이킹 할 수 없습니다.
트리쉐이킹을 위해서는 babel-plugin-lodash을 사용하거나 lodash-es를 사용하는 것을 추천합니다.

참고

webpack-bundle-analyzer 사용하기

webpack-bundle-analyzer를 사용하여 번들의 크기를 시각적으로 볼 수 있습니다.

// vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
  .BundleAnalyzerPlugin;

module.exports = {
    configureWebpack: {
    plugins: [
      new BundleAnalyzerPlugin({
        // analyzerMode: 'disabled'
      })
    ]
  }
}

참고