目次

  1. Turbopack の速度はどれくらいですか?
  2. Turbopack はなぜそれほど速いのでしょうか?
  3. Turbo エンジンの仕組み
  4. 必要に応じてコンパイルする
    1. ページレベルのコンパイル
    2. リクエストレベルのコンパイル
  5. なぜ Rust に基づいて開発するのでしょうか?
  6. Turbopack を選ぶ理由?
  7. 増分計算
  8. 怠惰な梱包
  9. Turbopackの機能
  10. Turbopack vs Vite vs WebpackTurbopack vs Vite
    1. Dev サーバーの開始時刻
    2. コードの更新
  11. Turbopack vs Webpack
    1. Dev server の開始時刻
    2. コードの更新
  12. Turbopack の未来

2022 年 10 月 25 日に、Next.js 13 が正式にリリースされます。 同時に、Vercel は次世代パッケージング ツールであるTurbopack を立ち上げ、オープンソース化しました。 Turbopack は、Java と TypeScript 用に最適化されたインクリメンタル パッケージング ツールで、Webpack の作成者である Tobias Koppers と Next.js チームによって Rust で作成されました。 Turbopack のリリースは多くの開発者の注目を集めています。Turbopack の利点を見てみましょう!

Turbopack の速度はどれくらいですか?

Turbopack は、可能な限り最速の開発エクスペリエンスを提供するために、新しいインクリメンタル アーキテクチャに基づいて構築されています。 大規模なアプリでは、Vite より 10 倍、Webpack より 700 倍速く更新されます。 通常、大規模なアプリケーションでは Vite よりも 20 倍高速です。

Turbopack には開発に必要な最小限のリソースのみがパックされているため、起動時間が非常に速くなります。 3000 モジュールを含むアプリでは、Turbopack の起動には 1.8 秒かかり、Vite の起動には 11.4 秒かかります。

Turbopack はなぜそれほど速いのでしょうか?

Turbopack のパフォーマンスの秘密は 2 つあります。高度に最適化されたマシン コードと、個々の関数のレベルまでキャッシュできる低レベルの増分計算エンジンです。 そのアーキテクチャは、Turborepo や Google の Bazel などのツールから教訓を得ており、どちらもキャッシュを使用して同じ作業の繰り返しを避けることに重点を置いています。

Turbo エンジンの仕組み

Turbopack が非常に高速なのは、Turbo Engine と呼ばれるインクリメンタル コンピューティングをサポートする再利用可能な Rust ライブラリ上に構築されているためです。 仕組みは次のとおりです。

Turbopack 主導のプログラムでは、特定の関数を"to be remembered"としてマークできます。 これらの関数が呼び出されると、Turbo エンジンは関数が呼び出された内容と返された内容を記憶します。 その後、それをメモリキャッシュに保持します。 簡略化した例を次に示します。

最初に、api.ts と sdk.ts の 2 つのファイルで readFile を呼び出します。 これらのファイルはパッケージ化され、結合されて、最終的に fullBundle が取得されます。 これらすべての関数呼び出しの結果は、後で使用できるようにキャッシュに保存されます。

sdk.tsの結果が変わっているため、再度パッケージ化して再度スプライスする必要があります。 重要なのは、apits は変わっていないということです。 キャッシュから結果を読み取って concat に渡すだけです。 したがって、読み取ったり再梱包したりする必要がなくなり、時間を節約できます。

現在、ターボ エンジンはキャッシュをメモリに保存しています。 これは、プロセスが実行している限りキャッシュが存続することを意味し、開発サーバーではうまく機能します。 将来的には、このキャッシュをファイル システムまたは Turborepo のようなリモート キャッシュに保存することが計画されています。 これは、Turbopack が複数の実行とマシンにわたって実行された作業を記憶できることを意味します。

このアプローチにより、Turbopack は適用される増分更新の計算を非常に高速に実行でき、Turbopack は開発中の更新を処理するように最適化されます。つまり、Dev server は常に変更に迅速に対応します。

必要に応じてコンパイルする

Turbo エンジンは、Dev server での非常に高速なアップデートの提供に役立ちますが、起動時間という考慮すべき重要な指標がもう 1 つあります。 Dev server の実行開始が速いほど、動作の開始も速くなります。 プロセスを高速化するには 2 つの方法があります。作業を高速化するか、作業量を減らすことです。 Dev server を起動するには、起動に必要なコードのみをコンパイルすることで作業負荷を軽減できます。

(1) ページレベルのコンパイル

2 ~ 3 年前の Next.js バージョンでは、アプリ全体をコンパイルしてから開発サーバーに表示していました。 Next.js 11 以降では、要求されたページのコードのみがコンパイルされます。 これは改善されましたが、完璧ではありません。 /users に移動すると、すべてのクライアント モジュールとサーバー モジュール、動的にインポートされたモジュール、参照された CSS と画像がバンドルされます。 つまり、ページの大部分が表示されない場合、またはタブの後ろに隠れている場合でも、コンパイルは実行されます。

(2) リクエストレベルのコンパイル

Turbopack は、要求されたコードのみをコンパイルするのに十分な機能を備えています。 これは、ブラウザが HTML をリクエストした場合、HTML のみがコンパイルされ、HTML によって参照されるものはコンパイルされないことを意味します。 ブラウザが CSS を必要とする場合、ブラウザは CSS のみをコンパイルし、参照する画像はコンパイルしません。また、Turbopack は、Chrome DevTools が開いていなければソース マップをコンパイルしないことさえ認識します。 リクエストレベルのコンパイルにより、リクエストの数が削減され、パフォーマンスが大幅に向上します。

なぜ Rust に基づいて開発するのでしょうか?

Turbopack は Rust 上で開発されており、Next.js チームが Java ベースのツールを Rust ベースのツールに移行するたびに、大幅な改善が見られました。 Next.js は、Java コンパイラ Babel を置き換えて最大 17 倍高速なコンパイルを実現し、Terser を置き換えて 6 倍高速な圧縮を実現すると同時に、ロード時間と帯域幅の使用量を削減します。

Turbopack を選ぶ理由?

Turbopack は Next.js の速度を向上させるために作成され、Webpack に代わる次世代の Web パッケージング ツールになることを期待しています。 それでは、新世代のパッケージング ツール esbuild と swc を選択するのではなく、独自のパッケージング ツールを作成することを選択してみてはいかがでしょうか?

増分計算

一般に、プロセスを高速化するには 2 つの方法があります。作業量を減らすか、並行して作業することです。 可能な限り最速の梱包ツールを構築するには、両方のレバーを強く引きます。 そこで、分散および増分動作のために再利用可能な Turbo ビルド エンジンを作成することにしました。 ターボ エンジンは関数呼び出しのスケジューラーのように機能し、利用可能なすべてのコアで関数を並行して呼び出すことができます。 ターボ エンジンは、スケジュールしたすべての機能の結果もキャッシュするため、同じ作業を 2 回実行する必要はありません。 要するに最小限の作業を最大速度で実行するということです。

他のツールは、「作業量を減らす」ために異なるアプローチを採用しています。 たとえば、Vite は開発モードでネイティブ ESM を使用することでワークロードを最小限に抑えます。 内部では、Vite は多くのタスクに esbuild を使用します。 esbuild は、ネイティブ ESM の使用を強制しない非常に高速なバンドラーです。 ただし、次のような理由により、esbuild は使用しないことが決定されました。

  • esbuild のコードは 1 つのタスク、つまり高速パッケージ化のために超最適化されているため、HMR (ホット アップデート) はありません。

  • esbuild は非常に高速なバンドラーですが、あまりキャッシュを行いません。 これは、多くの繰り返し作業を行うことを意味します。

そして、増分計算を備えた Rust 駆動のバンドラーは、大規模なスケールでは esbuild よりも優れたパフォーマンスを発揮します。

怠惰な梱包

Next.js の以前のバージョンでは、Web アプリケーション全体を開発モードでパッケージ化しようとしましたが、これは最適ではありませんでした。 Next.js の最新バージョンは、Dev server によって要求されたページのみをパックします。 たとえば、localhost:3000 に移動すると、pages/index.jsx とインポートされるモジュールのみがパッケージ化されます。

このより「遅延」なアプローチが、高速な Dev server の鍵となります。 そして、esbuild には「怠惰な」パッケージングの概念がありません。それはすべてか無かです。 Turbopack の開発モードは、受信したリクエストに基づいてアプリケーションのインポートとエクスポートの最小限のグラフを作成し、必要な最小限のコードのみをパックします。

この戦略により、最初に Dev server を起動するときの Turbopack が非常に高速になります。 ページをレンダリングするために必要なコードを計算し、単一のチャンクでブラウザに送信するだけです。 大規模な場合、これはネイティブ ESM よりもはるかに高速になります。

それが Turbopack が開発された理由です。

Turbopackの機能

Web アプリケーションを構築する実践は非常に多様です。 CSSだけでもSCSS、Less、CSS Module、PostCSSなどがあります。 React、Vue、Svelte などのフレームワークにはカスタム セットアップが必要です。

パッケージ化ツールを構築するときは、それがすぐに使用でき、設定が不要で、一部の機能はプラグインを通じて取得できることを望んでいます。 現在、Turbopack はまだアルファ段階にあり、現在の状態では Turbopack はまだ構成できないため、プラグインはまだ利用できません。

Turbopack のデフォルト設定ですぐに使える機能と、将来プラグインを通じてどの機能が設定されるかを見てみましょう。

  • Java: すべての ESNext 機能、Browserslist およびトップレベルの await をサポートします。

  • Type: 解決パスとbaseUrlを含む、すぐに使えるTypeをサポートします。

  • Imports: require、import、dynamic import などをサポートします。

  • Dev Server: 最適化された開発サーバーは、ホット アップデート (HMR) と高速リフレッシュをサポートします。

  • CSS: グローバル CSS、CSS モジュール、postcss ネスト、インポートをサポートします。

  • 静的リソース: /public ディレクトリ、JSON インポート、ESM 経由のリソース インポートをサポートします。

  • 環境変数: .env、.env.local などを通じて環境変数をサポートします。

Turbopack vs Vite vs WebpackTurbopack vs Vite

Turbopack は、次の 2 つの主要な指標で Vite を上回ります。

(1) Dev サーバーの開始時刻

Turbopack の Dev サーバー ver は、Vite よりもはるかに高速に起動します。 1000 モジュールのアプリケーションでは、Vite の起動に 4.8 秒かかります。 Turbopack はわずか 0.9 秒で起動し、5.5 倍高速になります。 大規模なアプリケーションでは、この違いは一貫したままになります。 30,000 モジュールのアプリケーションでは、Turbopack は Vite よりも 5.4 倍速く起動します。

(2) コードの更新

ファイルが変更されると、その変更をブラウザにレンダリングする必要があります。 それがより速く実行できるほど、フィードバックループがより緊密になり、リリースがより速くなります。 1000 モジュールのアプリケーションでは、Turbopack は Vite よりも 5.8 倍速くファイル変更を行いました。

Turbopack vs Webpack

Turbopack のインクリメンタル アーキテクチャは、次の 2 つの主要な指標において Webpack の速度を上回っています。

(1) Dev server の開始時刻

Turbopack の Dev サーバーは Webpack よりもはるかに速く起動します。 Next.js 12 は内部で Webpack を使用しており、1000 モジュールを含むアプリでビルド サーバーを 3.4 秒で起動できます。 Turbopack は 0.9 秒早く起動し、3.9 倍速くなります。

(2) コードの更新

Dev serverer で実行される最も一般的なアクションは、ファイルの変更です。 ファイルが変更されると、その変更をブラウザーにレンダリングする必要があります。 それがより速く実行できるほど、フィードバックループがより緊密になり、リリースがより速くなります。 1000 モジュールのアプリでは、Turbopack は Webpack よりも 8.9 倍速くファイル変更に反応しました。

Turbopack の未来

現時点では、Turbopack は Next.js v13 で利用できます。 スタンドアロン CLI、プラグイン API、および Svelte や Vue などの他のフレームワークのサポートが将来リリースされる予定です。

Turbopack は Next.js 13 Dev サーバーに使用されます。 これは超高速の HMR を強化し、React サーバー側コンポーネントや TypeScript、JSX、CSS などをネイティブにサポートします。 Webpack ユーザーは、Turbopack を使用して、Rust に基づいた将来の増分移行パスを開始することも期待できます。

Turbopack は、Webpack 作成者 Tobias Koppers のリーダーシップの下、Web 用の次世代パッケージングとなることが期待されています。