ウェブフロントエンド開発のビルド時間を短縮する方法

ビルド時間の短縮

開発の横山🐈です。
今回の記事では、ビルド時間を短縮する4つの方法をご紹介します。
弊社では Gulp と webpack を併用しているのもあり、想像以上に、ビルド時間が遅かったです・・😭

フロントエンドは開発中、高頻度でビルドを繰り返します。そのため、ビルド時間が長くなると、開発の作業効率や、ペースが乱され、集中力、意欲が削がれます。

現在のウェブフロントエンド開発において何かしらのモジュールバンドラーを使用されている方は多いのではないでしょうか?モジュールバンドラーも様々なものがありますが、2020年ではwebpackが標準だと思います。本稿を参考にビルド時間を短縮しましょう。
 

目次はこちら

  • 1.マシンスペックを上げる
  • 2.Gulpからwebpackへの処理をやめる
  • 3.キャッシュを有効にする
  • 4.development build の設定を見直す

 

マシンスペックを上げる

身も蓋もない話かもしれませんがマシンスペックを上げることで、ビルド時間が大幅に改善されました 🎉
弊社ではAWS上で開発環境を構築して開発を行っていました。

ですが、数ヶ月前から社内にサーバを一台設置し、新しく追加したサーバーで開発を行うようになってからは、かなり時間が短縮されました。
そちらに関してはこちらの記事を参考ください。

▼Proxmoxで開発環境を構築
 
開発チームの西村です。弊社では、learningBOXの開発にaws(Amazon Web Services)のインスタンスを使ってきたのですが、不都合な点もでてきたので、社内のサーバでの開発に切り替えようとしています。
 

AWS上での production build (キャッシュなし) の時間は 147.06s でした😱
社内サーバ上では 31.73s という結果なのでかなり効果がありました。

ですがいつまでもマシンスペックを上げて対応するのでは、どこかで頭打ちになってしまいますので別の方法でも改善する必要があります。
 

Gulpからwebpackへの処理をやめる

弊社ではwebpackは主にTypeScriptのトランスパイルに使用しています。
webpackは一つのエントリに対して一つのアウトプットが基本となっています。
ですが弊社は複数エントリかつ複数アウトプットです。
このため Gulp から webpack へ、トランスパイル後に再度 Gulp に渡していました。
ただ Gulp に関してはもう更新も少なく、できれば webpack に完全移行したいと考えました。
が、現状ではかなりコードを書き換えないと無理だということが判明しました 😭

そこで一旦 TypeScript だけでも webpack単体で動作するように修正しました。

webpackで複数エントリ&複数アウトプットを実現する場合、entryを下記の形にして渡す必要があります。

参考:Multi Page Application

module.exports = {
 entry: {
  pageOne: './src/pageOne/index.js',
  pageTwo: './src/pageTwo/index.js',
  pageThree: './src/pageThree/index.js'
 }
};

key に当たる部分が output の [name] に入ります。

module.exports = {
  output: {
    filename: '[name].bundle.js'
  }
};

上記の例では pageOne.bundle.js と出力されます。
ファイル数が少ない場合はこの方法で良いと思いますが、ファイル数が多い場合毎回ここに追加するのはかなり厳しいです。
なので Glob を使ってビルド対象のファイルを取得し、それを上記のentryの形にして渡すようにしました。
これでwebpack単体でファイルの取得、出力ができるようになりました。

この結果 production build (キャッシュなし) の実行時間は 31.73s → 17.97s と約半分近くになりました!
ただこの例は一般的ではないのであまり参考にならないかもしれません笑

 

キャッシュを有効にする

webpack 5 からキャッシュによる大幅な速度改善が見込めるようになりました。
下記のように設定することで有効になります。

module.exports = {
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename]
    }
  }
};

webpack 単体の時間は 15975 ms → 525 ms へと大幅に短縮されました!
全体としての時間は 17.97s → 9.21s になりました。
Gulp による JS と SCSS のビルド時間のほうが長くなってしまったので、production build の改善はここまでにしました。

 

development build の設定を見直す

production build はかなり改善しましたが、development build はどうでしょうか?
マシンスペックを上げた結果(キャッシュなし)
56.28s → 14.43s

TypeScript を webpack 単体で動作するように変更した結果 (キャッシュなし)
14.43s → 9.78s

キャッシュが有効な場合
9.78s → 4.51s

1分近くかかっていたものが5秒を切るようになりました 🎉

このままでも十分早くなりましたが、早いに越したことはありません。
なにかいい案はないかなと考えたところ、開発ビルド時はES5へのトランスパイルとTypeScriptの型チェックをやめることにしました。

ES5へのトランスパイル

弊社の learningBox は IE11でも動作するように開発しています。
ですがモダンなJavaScriptの記法はそのままではIE11で動作しません。
このためIE11でも動作するような記法(ES5)に変換しています。
基本的にはモダンブラウザで開発を行い、ある程度完成したらクロスブラウザの確認などを行っているので触っている時間としては モダンブラウザ > IE11 です。
賛否はあるとは思いますがこの部分を省けばより短縮できると考えました。

TypeScriptの型チェックをやめる

弊社開発チームでは主にVSCodeを使用しています。
VSCode と TypeScript の相性は良く、リアルタイムで型チェックを行ってくれます。
ですので開発中はVSCodeに型チェックは任せることにしました。
webpack で ts の loader に ts-loader を使用していましたが、development build においては esbuild-loader に変更しました。

上記2つを取り入れると
4.51s → 2.90s となり、ついに3秒を切りました!

 

差分ビルドに変更する

弊社では既に行っていましたが一応紹介させていただきます!
開発中にファイルを変更するたびにすべてのファイルをビルドし直すのは無駄だと思いますよね?
変更のあったファイルだけビルドしてくれればより早くなります。

参考:Watch and WatchOptions

watch 中だとビルド時間は数百msとなります!

 

以上が弊社での改善方法になります!皆様のご参考になれば幸いです。