ASP.NET Core Blazor WebAssembly ビルド ツールと事前 (AOT) コンパイル

Note

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

この記事では、スタンドアロン Blazor WebAssembly アプリのビルド ツールと、事前 (AOT) コンパイルを使用して、デプロイの前にアプリをコンパイルする方法について説明します。

この記事では主にスタンドアロン Blazor WebAssembly アプリに焦点を当てていますが、一部のモバイル デバイス ブラウザーのヒープ サイズに関するセクションは、Blazor Web アプリのクライアント側プロジェクト (.Client) にも適用されます。

.NET WebAssembly ビルド ツール

.NET WebAssembly ビルド ツールは、Web プラットフォーム用のコンパイラ ツールチェーンである Emscripten をベースにしています。 ビルド ツールをインストールするには、次の "いずれかの" 方法を使用します。

  • Visual Studio インストーラーの ASP.NET と Web 開発ワークロードの場合は、オプションのコンポーネントの一覧から [.NET WebAssembly ビルド ツール] オプションを選択します。
  • 管理コマンド シェルで dotnet workload install wasm-tools を実行します。

Note

.NET 6 プロジェクト用の .NET WebAssembly ビルド ツール

wasm-tools ワークロードでは、最新のリリース用のビルド ツールがインストールされます。 ただし、現在のバージョンのビルド ツールは、.NET 6 でビルドされた既存のプロジェクトと互換性がありません。 .NET 6 とそれ以降のリリースの両方をサポートすることが必要なビルド ツールを使用するプロジェクトでは、マルチターゲットを使用する必要があります。

.NET 7 SDK を使用してアプリを開発する場合は、.NET 6 プロジェクト用の wasm-tools-net6 ワークロードを使用します。 wasm-tools-net6 ワークロードをインストールするには、管理コマンド シェルから次のコマンドを実行します。

dotnet workload install wasm-tools-net6

Ahead-Of-Time (AOT) コンパイル

Blazor WebAssembly では、Ahead-Of-Time (AOT) コンパイルがサポートされています。これにより、.NET コードを直接 WebAssembly にコンパイルできます。 AOT コンパイルを使用すると、アプリのサイズが大きくなりますが、実行時のパフォーマンスが向上します。

AOT コンパイルが有効にされていない場合、Blazor WebAssembly アプリは WebAssembly に実装された .NET 中間言語 (IL) インタープリターを使ってブラウザー上で実行され、部分的に Just-In-Time (JIT) ランタイムがサポートされます (非公式には Jiterpreter と呼ばれます)。 .NET IL コードは解釈されるため、通常、アプリが実行される速度は、IL の解釈がないサーバー側の .NET JIT ランタイムの場合より遅くなります。 AOT コンパイルでは、アプリの .NET コードを WebAssembly に直接コンパイルし、ブラウザーによるネイティブ WebAssembly 実行ができるようにすることで、このパフォーマンスの問題に対処します。 AOT のパフォーマンスを向上すれば、CPU が集中的に使用されるタスクを実行するアプリの機能を大幅に強化することができます。 AOT コンパイルを使用する場合の欠点としては、AOT でコンパイルされたアプリは、一般に、IL で解釈される場合よりもサイズが大きくなるため、最初に要求されたときに、通常、クライアントへのダウンロードに時間がかかるということがあります。

AOT コンパイルが有効にされていない場合、Blazor WebAssembly アプリは WebAssembly に実装された .NET 中間言語 (IL) インタープリターを使ってブラウザー上で実行されます。 .NET コードは解釈されるため、通常、アプリが実行される速度は、サーバー側の .NET Just-In-Time (JIT) ランタイムの場合より遅くなります。 AOT コンパイルでは、アプリの .NET コードを WebAssembly に直接コンパイルし、ブラウザーによるネイティブ WebAssembly 実行ができるようにすることで、このパフォーマンスの問題に対処します。 AOT のパフォーマンスを向上すれば、CPU が集中的に使用されるタスクを実行するアプリの機能を大幅に強化することができます。 AOT コンパイルを使用する場合の欠点としては、AOT でコンパイルされたアプリは、一般に、IL で解釈される場合よりもサイズが大きくなるため、最初に要求されたときに、通常、クライアントへのダウンロードに時間がかかるということがあります。

.NET WebAssembly ビルド ツールのインストールに関するガイダンスについては、「ASP.NET Core Blazor WebAssembly ビルド ツールと事前コンパイル (AOT)」を参照してください。

WebAssembly AOT コンパイルを有効にするには、true に設定された <RunAOTCompilation> プロパティを Blazor WebAssembly アプリのプロジェクト ファイルに追加します。

<PropertyGroup>
  <RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>

アプリを WebAssembly にコンパイルするには、アプリを発行します。 Release 構成を発行すると、.NET 中間言語 (IL) リンクも実行されて、発行されたアプリのサイズが確実に縮小されます。

dotnet publish -c Release

WebAssembly の AOT のコンパイルは、プロジェクトが発行されたときにのみ実行されます。 プロジェクトが開発中 (Development環境) に実行される場合、AOT コンパイルは通常使用されません。これは、AOT コンパイルは通常、小さなプロジェクトでは数分かかり、大きなプロジェクトでは大幅に長くかかる可能性があるためです。 ASP.NET Core の将来のリリースで AOT コンパイルのビルド時間の短縮を実現できるように、開発に取り組んでいます。

AOT でコンパイルされた Blazor WebAssembly アプリのサイズは、通常、.NET IL にコンパイルされた場合のアプリのサイズよりも大きくなります。

  • サイズの違いはアプリに依存しますが、AOT でコンパイルされたアプリのほとんどは、IL コンパイルされたバージョンの約 2 倍のサイズになります。 これは、AOT コンパイルを使用すると、実行時のパフォーマンス向上のために読み込み時間のパフォーマンスが低下することを意味します。 このようなトレードオフがあっても AOT コンパイルを使用する価値があるかどうかは、アプリによって異なります。 CPU を集中的に使用する Blazor WebAssembly アプリは、通常、AOT コンパイルから最も恩恵を受けます。

  • AOT でコンパイルされたアプリのサイズが大きくなるのは、次の 2 つのことのためです。

    • ネイティブ WebAssembly で高レベルの .NET IL 命令を表すには、より多くのコードが必要です。
    • アプリが発行されるとき、AOT ではマネージド DLL がトリミング "されません"。 Blazor では、リフレクション メタデータ用に、および特定の .NET ランタイム機能をサポートするために、DLL が必要です。 クライアントで DLL が必要であるためにダウンロード サイズは増加しますが、.NET エクスペリエンスとの互換性は高くなります。

Note

Mono/WebAssembly MSBuild のプロパティとターゲットについては、WasmApp.Common.targets (dotnet/runtime GitHub リポジトリ) を参照してください。 一般的な MSBuild プロパティに関する公式ドキュメントの提供は、ドキュメント blazor msbuild 構成オプション (dotnet/docs #27395) によって計画されています。

Ahead-Of-Time (AOT) コンパイル後に .NET IL をトリミングする

WasmStripILAfterAOT MSBuild オプションを使用すると、WebAssembly への AOT コンパイルの実行後、コンパイルされたメソッドの .NET Intermediate Language (IL) を削除できます。これにより、_framework フォルダーのサイズが小さくなります。

アプリのプロジェクト ファイル内で:

<PropertyGroup>
  <RunAOTCompilation>true</RunAOTCompilation>
  <WasmStripILAfterAOT>true</WasmStripILAfterAOT>
</PropertyGroup>

この設定は、ほとんどのコンパイルされたメソッド (ライブラリのメソッドやアプリ内のメソッドを含む) の IL コードをトリミングしてなくします。 コンパイルされたメソッドの一部は実行時に .NET インタープリターによって引き続き必要とされるため、すべてのコンパイルされたメソッドをトリミングできるわけではありません。

トリミング オプションに関する問題を報告するには、dotnet/runtime GitHub リポジトリで issue を作成します。

アプリが正常に実行されなくなる場合は、トリミング プロパティを無効にします。

<WasmStripILAfterAOT>false</WasmStripILAfterAOT>

一部のモバイル デバイスのブラウザーのヒープ サイズ

クライアント上で実行され、モバイル デバイスのブラウザー (特に iOS 上の Safari) を対象とする Blazor アプリをビルドする際には、MSBuild プロパティ EmccMaximumHeapSize を使用してアプリの最大メモリを減らすことが求められる場合があります。 詳しくは、「ASP.NET Core Blazor WebAssembly のホストと展開」をご覧ください。

ランタイムの再リンク

Blazor WebAssembly アプリの最大部分の 1 つは、WebAssembly ベースの .NET ランタイム (dotnet.wasm) です。これは、このアプリがユーザーのブラウザーから最初にアクセスされたときに、ブラウザーによってダウンロードされる必要があります。 .NET WebAssembly ランタイムを再リンクすると、未使用のランタイム コードが削除されるため、ダウンロード速度が向上します。

ランタイムの再リンクには、.NET の WebAssembly ビルド ツールをインストールする必要があります。 詳しくは、「ASP.NET Core Blazor 用のツール」をご覧ください。

.NET WebAssembly ビルド ツールをインストールすると、ランタイムの再リンクは、アプリが Release 構成で公開されるときに自動的に実行されます。 サイズは、グローバリゼーションを無効にしたときに、特に大きく縮小します。 詳しくは、「ASP.NET Core Blazor のグローバリゼーションおよびローカライズ」をご覧ください。

重要

ランタイムの再リンクの場合、JavaScript で呼び出し可能なクラス インスタンス .NET メソッドは、保護されていない限り、トリミングされます。 詳細については、「ASP.NET Core Blazor で JavaScript 関数から .NET メソッドを呼び出す」を参照してください。

Single Instruction Multiple Data (SIMD)

WebAssembly Single Instruction Multiple Data (SIMD) では、1 つの命令を使って複数のデータに対する操作を並列で実行することで、ベクター化された計算のスループットを向上させることができます。 SIMD は既定で有効になっています。

SIMD を無効にするには、たとえば、SIMD をサポートしていない古いブラウザーまたはモバイル デバイス上のブラウザーをターゲットにする場合、アプリのプロジェクト ファイル (.csproj) で <WasmEnableSIMD> プロパティを false に設定します:

<PropertyGroup>
  <WasmEnableSIMD>false</WasmEnableSIMD>
</PropertyGroup>

詳細については、「.NET WebAssembly アプリケーションの構成とホスト: SIMD - 単一命令、複数のデータ」を参照してください。ガイダンスはバージョン管理されておらず、最新のパブリック リリースに適用されることに注意してください。

WebAssembly Single Instruction Multiple Data (SIMD) では、1 つの命令を使って複数のデータに対する操作を並列で実行することで、ベクター化された計算のスループットを向上させることができます。 SIMD は既定では無効になっています。

SIMD を有効にするには、アプリのプロジェクト ファイル (.csproj) で <WasmEnableSIMD> プロパティ セットを true に追加します。

<PropertyGroup>
  <WasmEnableSIMD>true</WasmEnableSIMD>
</PropertyGroup>

詳細については、「.NET WebAssembly アプリケーションの構成とホスト: SIMD - 単一命令、複数のデータ」を参照してください。ガイダンスはバージョン管理されておらず、最新のパブリック リリースに適用されることに注意してください。

例外処理

例外処理は、既定で有効になっています。 例外処理を有効にするには、アプリのプロジェクト ファイル (false) で <WasmEnableExceptionHandling> プロパティを .csproj の値で追加します。

<PropertyGroup>
  <WasmEnableExceptionHandling>false</WasmEnableExceptionHandling>
</PropertyGroup>

WebAssembly 例外処理を有効にするには、アプリのプロジェクト ファイル (.csproj) で <WasmEnableExceptionHandling> プロパティを true の値で追加します。

<PropertyGroup>
  <WasmEnableExceptionHandling>true</WasmEnableExceptionHandling>
</PropertyGroup>

その他のリソース