0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

細かすぎるViteのチャンク問題

Posted at

ViteでJavaScriptプロジェクトをビルドしてみたところ、想定以上に細切れとなりましたが、調整したら緩和できました。

TL; DR

  • ViteはES Moduleネイティブで、ブラウザのimportを使うような結果を生成する
  • コードの過不足がないように分割するので、細かくなりすぎることがある
  • Rollup側のoutput.experimentalMinChunkSizeで改善可能

ViteとWebpackの違い

既存のプロジェクトをWebpackからViteに乗り換えたのですが、考え方が大きく異なりました。

Webpackは、CommonJS全盛期の2014年に初版が作られたソフトウェアで、のちにES Moduleにも対応してきたとはいえ、モジュール管理はWebpack自身が追加したコードによって処理されています。また、CommonJS
ではモジュールの呼び出しがrequireという関数であるため、モジュールの切れ目はコードを書く側が意識しなければならず、うっかりすると同じモジュールが複数箇所に取り込まれる、ということになってしまいました。

これに対してViteは、ES Moduleのブラウザネイティブ対応が進んでから登場したツールで、Vite自身が取り扱うモジュール構造も出力結果もES Moduleとなっており、import/exportもブラウザにある機能をそのまま使う形となっています1

そして、importが静的な構文ということもあり、もとのソースコードでimportされていたファイルを別ファイルとしておく、ということも当たり前に行われて、同じコードが重複しないことを優先する形のビルド結果となります。

気になった問題点

そこまではいいのですが、動的なimport()でファイルを切り分けるようにしていたプロジェクトで、「このファイルはこっちに入る」というパターンが細分化されてしまい、最小は文字列定数が1つというようなファイルを含め、100個以上のJavaScriptファイルが散らかる事態となってしまいました。

流石にここまで来ると、過不足なくコードを読み込めるメリットより、ファイル数が増えるデメリットを考えざるを得ません。

設定による対策

調べてみると、Viteから使うRollup側の設定にoutput.experimentalMinChunkSizeというものがありました。

ドキュメントで詳細を確認してみましたところ、概ね以下のような感じでした。

  • 指定した容量以上になることを目指してチャンクをまとめる
  • まとめた結果として、使わないコードが付いてくる形になる箇所が発生する
  • 容量の基準はTree shaking後、minify前
  • 副作用などを考え合わせて、マージされないこともありうる

実際に指定をかけた結果、JavaScriptチャンクは半減以下となりました。なお、動作を見ていたところ、「ふつうにチャンクを作る」→「マージできるか調べる」という流れになっていました。そして副作用があるとの判断で別チャンクになった箇所も確認できました。

  1. Viteの開発モードではバンドルも積極的には行わず、ソースコードの1ファイル単位で変換を行ってはブラウザで直接読み込むという構造となりますが、今回の主題はリリースビルドの方なので、そちらを掘り下げるのは割愛します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?