ここ1年位で良く聞くようになったVite。Vue.jsの生みの親であるEvan Youさん開発、との事なので、
Vue.jsとの親和性が高いのだろうな、と。Laravel + Vue.js のスタックで開発する機会があれば使ってみたいな、と。
私の中ではその程度の位置付けでした。
しかし、今年の6月、Laravel 9.2.0のリリース時のTaylerさんの以下のツイートを見て、認識を改めました。
Today we're pumped to announce that new Laravel projects use Vite to bundle frontend assets. Breeze and Jetstream have been updated as well. 🔥
Experience lightning fast Hot Module Replacement when using the new Breeze / Vite stack with Inertia Vue or React. ⚡
— taylor otwell 🪐 (@taylorotwell) June 28, 2022
光速のHMR。。。是非使ってみたい!
Viteが採用された理由
従来のLaravelはアセットバンドラにwebpackをラップしたLaravel-Mixを使うのが一般的でした。
この決定を知った時、私はViteについて冒頭に述べた程度の認識だったので、
「なぜViteに変えるの?Laravel-Mixの何がダメなの?」と、思いました。
因みに、同様の質問がTwitterで投げられており、Taylerさんがシンプルに
“much faster(断然速いから)”と答えていました。
この業界においてスピードは正義ですから、より速いツールが開発されたら導入しない理由はないですよね。
でも何がどう速いのでしょうか?もっと知りたくなり調べてみました。
調べていく内に、Laravel-MixとViteは全く別物、ということが分かってきました。
Laravel-Mixの問題点
Viteが速いということは、Laravel-Mixが遅いという事ですが、具体的にどの部分が遅かったのでしょうか?
従来のLaravelの開発ではnpm run dev
を実行すると、resources配下から必要なアセットファイル(cssやjsなど)をかき集め、依存関係を解決しつつ1ファイルにまとめるという処理が行われていました。
アセットバンドルについてはlaravel-mixでフロントエンドを開発にてkhino氏が詳しく解説しているので是非ご一読下さい。
開発者のアクションとしては、
- jsファイルを変更する
- npm run dev を実行しアセットをバンドル(ビルドともいう)する
- ビルドした成果物をブラウザで確認する
といった感じです。
プロジェクト規模が大きくなりファイル数が多くなるとバンドル処理に時間が掛かり、開発効率が落ちてしまいます。
私のようにjsをふりかけ程度にしか使っていない場合は大したこと無いですが、VueでSPAを開発している場合などは、
上記のフローを高頻度で繰り返し開発するため、変更〜確認までにラグがある事は大きなストレスになります。
Viteはノーバンドル
ではViteはどうなのか?
公式ページに詳しく書いてありますが、Viteは開発サーバにおいて基本バンドルしません。パッケージやライブラリなど開発者が基本変更しないようなファイルは事前バンドルされるのですが、開発者が頻繁に変更するソースコードについてはバンドルせずブラウザに提供するのです。
最近のブラウザはES6で導入されたモジュール機能(import, export)に対応しており、ブラウザが表示するページに必要なモジュールを把握しそれらをimportしてくれます。そして、開発者がファイルを編集した際はViteがその変更を把握し、変更されたモジュールのみ再読み込みしてくれるのです。
アセットのバンドルも無ければ、リロード範囲も最小限な為、前項で問題とした変更〜確認までのラグというのが最小限に抑えられるという訳です。
Viteを体感してみる
冒頭のTaylerさんのTweetにある通り、Laravel 9.2.0 以降ではViteがフロントエンドのデフォルトビルダとして採用されており、npm run dev
を実行するとViteがHMRモードで起動します。
HMRとはHot Module Replacement
の略でコードを変更し保存するとページのリロード無しでブラウザに変更が反映されます。
驚いたのは、保存してからブラウザに反映されるまでの速さです。文字通り一瞬で全くラグを感じませんでした。Vite恐るべし。
本番用にはバンドルする
開発時においてはバンドルせずにアセットを提供する事で開発者をハッピーにしてくれるViteですが、本番においてはバンドルした方がハッピーな様です。
なぜなら、ノーバンドルでアセットを提供した場合、ブラウザが逐次必要なモジュールをネットワーク経由で取得する必要があり非効率だからです。通常ネットワーク経由でデータを取得する際、細切れになったデータをロードするよりも、それらを1つにまとめてロードした方が効率的なのです。
開発時においてそれが問題にならないのは取得するデータが全てローカルに存在し、ネットワーク経由で取得する必要が無い為です。
まとめ
長く(と言っても数年)Laravel-Mixを使って開発していると、ついアセットはバンドルするもの、という固定観念に縛られがちですが。
開発時は敢えてバンドルせず、ブラウザ側で出来ることはブラウザに任せよう、という思い切った試みがパズルのピースのように完璧にバチッとはまっており、改めて素晴らしい発明だなぁ、と思いました。Evan Youさん、あっぱれです。