- webpack 4.16.0
概要
webpack4のデフォ設定でチャンク分割がどのように行われるのか確認した。
ついでに分割されたチャンクがブラウザ上でlayzyloadされるかも確認したい。
本家説明書では想像しにくいケースごとの説明がこの記事で4パターン解説されていたので、それをコードにして実際にバンドルしてみた。
基本動作
以下の条件を全部満たすとチャンクに分割される
- 共有されているかnode_modules以下のモジュールである
- 30kb以上である (minify, gzip前)
- チャンクが要求されロードするときの同時リクエスト数が5以下である
- ページ表示時の同時リクエスト数が3以下である
3と4はよくわからんかった。
実験
冗長なので1つ目のサンプルについてだけ。
エントリーポイントでは、テスト用のモジュールをdynamic importする。
あとでランタイムでlayzyloadされるか見たいので、promiseの解決時にログを吐いておく。
import('./chunk-a').then(() => { console.log('chunk-a loaded'); });
import('./chunk-b').then(() => { console.log('chunk-b loaded'); });
import('./chunk-c').then(() => { console.log('chunk-c loaded'); });
import('./chunk-d').then(() => { console.log('chunk-d loaded'); });
各チャンクの中身
- a react, react-dom, 適当なコンポーネントA
- b react, react-dom, 同B
- c angular, 同C
- d angular, 同D
条件確認
- reactやangularはnode_modules以下のモジュールであり、複数のチャンクで利用されている。 (reactがaとb, angularがcとd)
- reactもangularも30kb以上である。
- チャンクに対してのロード数が本体とモジュールの2
- ロード時のリクエスト数は1のまま (?ここ自信ない)
バンドル結果
条件に該当するので、めでたくreactやangularが分割される。
dynamic import
を明示したモジュールは強制的に分割されるっぽい。
production
でバンドルしてしまったが、 development
でやったほうが実験としては妥当だった・・・
99K 0.js react, react-dom
176K 1.js angular
129 2.js chunk-d, ComponentD
129 3.js chunk-c, ComponentC
134 4.js chunk-b, ComponentB
134 5.js chunk-a, ComponentA
2.4K sample1.js
ブラウザ上での動作
適当なHTMLをwebpack-serveでホストしてエントリーポイントを読み込んだ場合のネットワークの様子をgifアニメに記録した
順をおっていくと
1. エントリーポイントをダウンロードする
2. 分割されたモジュールをダウンロードする
3. reactが含まれる 0.js
のダウンロードが終わり chunk-a, chunk-b のプロミスが解決される
4. angularが含まれる 1.js
のダウンロードが終わり chunk-c, chunk-d のプロミスが解決される
まとめ
webpackのチャンク分割の動作を確認した。
dynamic import
すると条件に従って自動的に分割される。
ブラウザ上でlayzyloadもされる。
べんりー。