ES Modulesを優先的にロードするmodulepreload
Published at 2017-11-26
<link>
要素の rel
属性に、新しく modulepreload
という値が ES Modules を先行してロードする仕様として追加され、Chrome 64 に実装された。リソースを先行してロードする手段としては既に <link rel="preload">
があり、スクリプトファイルには as="script"
を指定すれば良いが、ES Modules をロードするためにはいくつか問題があり、新しく rel="modulepreload"
が検討されている。
<link rel="preload" as="script">
ではダメなのか
もとい <link rel="modulepreload">
にすべき理由が Preload and Modules に書かれている。
<link>
要素によるリクエストの credential が<script>
要素と一致している必要がある- 事前に module なのかどうかわかっていないとパースに困る (v8 固有?)
<link rel="preload">
は単一リソースをロードする仕様である- 保存先が preload cache ではなく module map である必要がある (chrome 固有?)
<link rel="preload">
の保存先は preload cache/HTTP cache である
as=""
で対応しようとするとmodulescript
/moduleworker
/modulesharedworker
/moduleserviceworker
と、様々な値を定義しなくてはならない
つまり Normal Script と Module Script を区別する必要アリということだ。
Module Preload は、Preload では実施しない Module Script が依存するモジュールの解決も行うことで、依存関係を探すレイテンシーを省ける。
<link rel="modulepreload">
の振る舞い
- Module Script をロードし module map に追加する
- ゆくゆく必要になる依存モジュールのロードのために、ヒントとして記録する
- ユーザーからは見えない
ES Modulesが抱えるパフォーマンスの問題
現時点で ES Modules は、モジュールの数が多かったり、依存が深かったりするとパフォーマンス上で劣るという課題がある。もちろん実装の最適化はされていくと思うが。
モジュール数100以上 or 深さが5以上ならbundleした方がいいとのこと "Loading Performance with (Many) Modules: Summary as of Oct 7, 2017 - Go…" https://t.co/8gZZBbejMn
— azu (@azu_re) 2017年10月13日
対策案はいくつかありそうだが、この <link rel="modulepreload">
を使って優先的に Module Script をリクエストしておけば、モジュールをバンドルせずとも改善が見込める。