Help us understand the problem. What is going on with this article?

Nuxt.jsのbundleサイズを55%削減したwebpack周りの小技

More than 1 year has passed since last update.

Nuxt.jsとLaravelを使って「Devicebook」(https://devicebook.me)というWebサービスを個人開発しています。
今回はNuxt.jsのwebpack周りを改善し、bundleファイルを151kbから67kb(約55%の削減)にした方法をご紹介します。

webpack-bundle-analyzerで分析

Nuxt.jsでは標準でwebpack-bundle-analyzerが組み込まれており、これでbundleされたファイルの中身を分析できます。

nuxt.config.js
build: {
  analyze: true
}

anayzeオプションをtrueにし、Nuxt.jsプロジェクトをビルドしてみましょう。そうすれば以下のような画面が開かれます。

b863486d03c6e960d8444a9b73e670ed.png

この画像が改善前のファイルです。これを参考にしながら削れそうな所を探していきます。

55%の削減ができた3つのポイント

1. lodashのimportを改善する(24kb→5kb)

lodashをimport _ from 'lodash'のように読み込んでしまうと、全てのlodash関数などがbundleされてしまいます。
それを回避するため、使用する関数のみをimportするように変更します。

~/utils/my-util.js
// import _ from 'lodash'
import escape from 'lodash/escape'

export default function (string) {
  // ...
  return escape(string)
}

これでbundleされるのはescape関数のみとなります。lodashはgzippedのものでも25kbほどあるため、きちんと気をつけておきましょう。

2. Vuetifyのa-la-carte(110kb→20kb)

VueのマテリアルUIフレームワークといえばVuetify.jsが人気でわたしもお世話になっています。
しかしそのままVue.use(Vuetify)のようにしてしまうと、Vuetifyの全てのコンポーネントなどがbundleされてしまいます。

そこでa-la-carte(フランス語で、メニューから選んだ/お好みの料理の、などの意味)にimportする必要があります。
詳細はVuetify.jsのドキュメントに書いてあるのでそちらを参照してください。
https://vuetifyjs.com/ja/guides/a-la-carte

3. Vue.jsの Dynamic Import(20kb→5kb)

例えば以下の様に、デバイスによって表示するコンポーネントを切り替えたい時があります。

MyComponent.vue
<template>
  <div>
    <MobileComponent v-if="$device.isMobile"/>
    <DesktopComponent v-else/>
  </div>
</template>

<script>
import MobileComponent from './MobileComponent'
import DesktopComponent from './DesktopComponent'

export default {
  components: { MobileComponent, DesktopComponent }
}
</script>

この時、スマホのユーザーにはMobileComponentしか表示しませんが、DesktopComponentも一緒にbundleされたjsファイルを読み込んでしまいます。

それを回避するため、Vue.jsには非同期コンポーネントという機能があります。
非同期コンポーネントを利用するためには、以下のように修正します。

MyComponent.vue
<script>
export default {
  components: {
    MobileComponent: () => import('./MobileComponent'),
    DesktopComponent: () => import('./DesktopComponent')
  }
}
</script>

こうすることで、MobileComponentとDesktopComponentが一緒にbundleされることはなく、ユーザーは片方のcomponentファイルを読み込みます。

他のよくある改善点

例えばDateTimeライブラリであるmomentはかなりサイズが大きいため、シンプルな時間操作のみを求めているのであればDay.jsという2kbに軽量ライブラリがおすすめです。
またmomentを利用する場合には必要なロケールのみを読み込むなどをして余計なファイルをbundleしないようにしましょう。

それでは、皆さんも良きNuxt.js生活を!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした