⚡️

Viteはなぜ速い

2022/08/03に公開

この記事の目的

The State of JS 2021のビルドツールランキングでも、満足度興味で一位を獲得しているVite、人気のツールですよね。
the-state-of-js-2021
https://2021.stateofjs.com/ja-JP/libraries/build-tools

「個人開発でViteを使ってみたい!」「会社のプロジェクトでViteに移行する案がある!」という方も多いかも知れません。私もその一人です。
ただ、「Viteは速い!」ということ以外よくわかってない。なんで速いの?従来の他のツールと何が違うの?という疑問について、仕組みの基本的なところを整理してみた記事です。

Viteとは何をするツール?

まずはそもそも何をするツールかということから整理すると、Viteが担っている役割としては、開発環境の構築と、本番環境のビルドです。
開発環境の構築は、非常に高速なGo言語で開発されたesbuildを使っています。
一方、本番環境のビルドコマンドは、Rollupを利用しています。
なぜ開発環境の構築と、本番環境のビルドコマンドで使っているツールが違うのかというと、超高速なesbuildですが、アプリケーションをバンドルするために必要とされる重要な機能のいくつかが開発途中だから、現時点での最適解であるRollupを利用したという理由のようです。(参照:なぜ-esbuild-でバンドルしないのか?)

Viteと同じポジションのツールとしては、webpack, parcel, Snowpackといったところが挙げられるかと思います。

バンドルは遅い。ブラウザのネイティブESMを利用すれば高速になる。

早速本題の「Viteはなぜ速い」のか、について触れていきます。

従来のバンドラベースのビルドセットアップ

まずはwebpackなどの従来のバンドラベースのビルドセットアップの仕組みを、以下添付画像を見てみましょう。
ざっくりとした説明になりますが、バンドラベースのビルドセットアップでは、アプリケーションを提供する前に、バンドルという工程によって、複数のJavaScriptコードを1つの大きなコードに合体させ、ブラウザで実行可能にするための調整処理をします。
アプリ全体の内容を含む大きなコードを生成することから、バンドラベースのビルドセットアップの仕組みは、アプリが大きくなるほど必然的に遅くなってしまう問題点があります。

bundle-based-dev-server
(画像元:https://ja.vitejs.dev/guide/why.html)

ネイティブESMを利用したビルドセットアップ

一方、ViteはネイティブESMを利用して高速化しています。
ざっくりイメージを持つために、以下の添付画像と、ネイティブESMとは何かについてみていきましょう。

ネイティブESM

ネイティブESMとは何かですが、ネイティブESMはES Modulesのことです。(import宣言でインポートし、export宣言でエクスポートする構文)
ES Modulesは、ECMAScript仕様の一部として定義されたモジュールシステムのことで、ブラウザによって直接理解されます。
「ネイティブESMを利用する」という意味ですが、ブラウザがES Modulesを直接理解することを利用して、ビルド後の成果物を複数ファイル・モジュールのまま、ブラウザにそれらを直接読み込ませることを指します。
Viteは、このネイティブESMを利用することで、アプリケーション全体のバンドルという重たい工程を不要にし、高速化を可能にしています。

native-esm-based-dev-server
(画像元:https://ja.vitejs.dev/guide/why.html)

ネイティブESMを利用するための、Viteの処理

ViteはネイティブESMを利用すると言いましたが、その為の事前処理として、アプリケーションのモジュールを以下の2つのカテゴリに分割します。

  • 依存関係: 開発中あまり変更されないプレーンなJavaScript(例:MUIなどのコンポーネントライブラリ)
  • ソースコード: 変換を必要とするJSX, CSS, Vue/Reactなどのコンポーネント

依存関係
依存関係に分割されるコードは、事前バンドルという工程によって、CommonJSまたはUMD(Universal Module Definition)を、ESMに変換します。この処理の目的は、以下の2点です。

  • ブラウザに、ECMAScriptモジュールとしてコードを提供できるようにする。
  • ページロードのパフォーマンス向上させる。(多くの内部モジュールを持つ依存関係を、単一のモジュールに変換する処理)

事前バンドルもesbuildを使用しているので、JavaScriptベースのバンドルよりも10倍から100倍高速ということです。
依存関係の事前バンドル | Vite

ソースコード
Viteはブラウザのリクエストに応じて、ソースコードを変換しネイティブESMを利用して提供するのみになります。

開発中のファイル変更際の更新も高速

上記の仕組みにより、Viteは開発時の再バンドルもないので開発が快適です。
HMR(全体リロードではなく変更があったモジュールのみを差し替える最適化)をネイティブESM上で行うことで、アプリケーションのサイズに関係なく一貫して高速で実行されます。

まとめ

筆者も最近Viteを使っていますが、スピードがもろに実感できて、開発がすごく快適です。
皆さんもぜひVite試してみてください。
以下のStackBlitzでViteをオンラインで試すこともできます。
https://stackblitz.com/edit/vitejs-vite-sqdtjb?file=javascript.svg&terminal=dev

参照

This article is also available in English: https://dev.to/takuyakikuchi/why-is-vite-so-fast-163p

GitHubで編集を提案

Discussion