🐈

Viteがサポートしている各minifierを試してみる

2024/01/07に公開

はじめに

Vite のビルドプロセスにはデフォルトで esbuild による minify が含まれています。他にも設定できる minifier があるので、それぞれ試してビルド時間とバンドルサイズを比較してみました。

検証した環境

  • Vite v5.0.11

前提

create-vite の Vite + React + TypeScript テンプレートで作成したアプリを対象に動作確認します。

minify とは

minify はインデントやコメントを削除したり、変数・関数名を短くするなどしてファイルサイズを小さくする処理です。ファイルサイズが小さくなることで、ファイルの読み込み時間を短縮し、パフォーマンスを向上させることができます。

minifier の指定方法

build.minify

build.minify を指定することで、JS・CSS の minifier を適用できます。CSS の minifier は後述する方法で上書き可能ですが、デフォルトは build.minify と同じになります。

build.cssMinify

前述の通り、CSS のデフォルトの minifier は build.minify で指定しているものになります。CSS の minifier を変えたい場合は build.cssMinify を指定することで変更可能です。

各 minifier を試す

バンドルサイズは下記のファイルサイズをもとに比較します。

  • dist/assets/index-xxx.js
  • dist/assets/index-xxx.css

esbuild

JS・CSS ともにデフォルトで使用される minifier です。そのため、追加の設定は不要です。

vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
})

ビルド時間とバンドルサイズ

yarn build
yarn run v1.22.19
$ tsc && vite build
vite v5.0.11 building for production...
✓ 34 modules transformed.
dist/index.html                   0.46 kB │ gzip:  0.30 kB
dist/assets/react-h3aPdYU7.svg    4.13 kB │ gzip:  2.14 kB
dist/assets/index-4sK4E3Wk.css    1.39 kB │ gzip:  0.72 kB
dist/assets/index-YnIXOLyF.js   143.39 kB │ gzip: 46.11 kB
✓ built in 356ms
✨  Done in 1.64s.

ビルドにかかった時間は 1.64s でした。
続いてバンドルサイズですが、index-xxx.js が 143.39KB、index-xxx.css が 1.39KB でした。

Terser

Vite v3 以降は Vite のバンドルサイズを小さくするためオプションの依存関係になったようです。詳細は下記のPRを参照ください。
https://github.com/vitejs/vite/pull/8049

そのため、Terser を使用する場合、別途 terser をインストールする必要があります。

yarn add -D terser

build.minifyterser を指定します。

vite.config.ts
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react-swc'
 
 // https://vitejs.dev/config/
 export default defineConfig({
   plugins: [react()],
+  build: {
+    minify: 'terser',
+  }
 })

ビルド時間とバンドルサイズ

yarn build
yarn run v1.22.19
$ tsc && vite build
vite v5.0.11 building for production...
✓ 34 modules transformed.
dist/index.html                   0.46 kB │ gzip:  0.30 kB
dist/assets/react-h3aPdYU7.svg    4.13 kB │ gzip:  2.14 kB
dist/assets/index-4sK4E3Wk.css    1.39 kB │ gzip:  0.72 kB
dist/assets/index--6oMmeLt.js   142.77 kB │ gzip: 45.85 kB
✓ built in 1.04s
✨  Done in 2.03s.

ビルドにかかった時間は 2.03s でした。
続いてバンドルサイズですが、index-xxx.js が 142.77KB、index-xxx.css が 1.39KB でした。

Lightning CSS

Lightning CSS もオプションの依存関係となっているため、別途インストールする必要があります。

yarn add -D lightningcss

CSS 用の minifier なので、build.cssMinify に指定します。

vite.config.ts
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react-swc'
 
 // https://vitejs.dev/config/
 export default defineConfig({
   plugins: [react()],
   build: {
-   minify: 'terser',
+   cssMinify: 'lightningcss',
   },
 })

ビルド時間とバンドルサイズ

yarn build
yarn run v1.22.19
$ tsc && vite build
vite v5.0.11 building for production...
✓ 34 modules transformed.
dist/index.html                   0.46 kB │ gzip:  0.30 kB
dist/assets/react-h3aPdYU7.svg    4.13 kB │ gzip:  2.14 kB
dist/assets/index-wizrbhps.css    1.55 kB │ gzip:  0.79 kB
dist/assets/index-YPOQ70dU.js   143.39 kB │ gzip: 46.11 kB
✓ built in 371ms
✨  Done in 1.05s.

ビルドにかかった時間は 1.05s でした。
続いてバンドルサイズですが、index-xxx.js が 143.39KB、index-xxx.css が 1.55KB でした。

結論

これまで検証した結果をまとめると次のようになりました。

esbuild Terser esbuild + Lightning CSS
JS size 143.39KB 142.77KB 143.39KB
CSS size 1.39KB 1.39KB 1.55KB
Time 1.64s 2.03s 1.05s

esbuild は Terser と比べると、ビルド時間が短い代わりにバンドルサイズは少し大きくなっています。この違いは Vite の公式ドキュメントでも説明されています。
https://vitejs.dev/config/build-options#build-minify

続いて、Lightning CSS ですが、esbuild よりビルド時間がさらに短くなっています。代わりにバンドルサイズも少し増えています。

まとめると、バンドルサイズが最も小さいのは Terser でビルド時間が最も短いのは esbuild + Lightning CSS となりました。

とはいえ、いずれも一長一短なので、開発しているプロダクトで何を優先したいか によって最適なものは変わってきそうです。

個人的にはバンドルサイズが許容できるのであれば、esbuild を使いたいと思っています。
また、今後 Lightning CSS の experimental が外れたら、JS の minifier は esbuild、CSS の minifier は Lightning CSS という構成も良さそうかなと思っています。

参考

Discussion