ブレイザー・インタラクティビティ
Blazorは、 サーバー、 WebAssembly、 オートの3つのインタラクティブモードのいずれかでポータルを発送できます。このモードでは、インタラクティブコンポーネントがどのように動作するか(サーバー上のSignalR接続、ブラウザでコンパイルされた.NET経由で、またはその両方で)を選び、プロジェクトレイアウトで何が生成されるかを決定します。Power Portals Proは3つすべてで正しく動作します。違いはフレームワークの機能ではなく、展開の形状やプロジェクトの配線にあります。
三つのモード
サーバー
インタラクティブコンポーネントはサーバー上で実行されます。接続された各ユーザーはホストへのオープンなSignalR接続を保持し、すべてのUIイベントはサーバーへの往復を行います。
- 最小のクライアントダウンロード。 ブラウザは単純なHTMLと小さなSignalRローダーを受け取ります — クライアントには.NETランタイムは提供されません。
- サーバー機能もフルです。 コンポーネントはHTTPを経ずに、Dataverseクライアント、設定、ファイルシステムなどのサーバーサイドサービスに直接注入します。
- 最もシンプルな展開です。 1つの ASP.NET Coreホストで、公開する別のWebAssemblyバンドルはありません。
トレードオフ:
- ステートフルホスト。 各ユーザーの回線は単一のサーバーインスタンスにピン留めされています。水平スケーリングにはスティッキーセッションが必要で、ホストの再起動はすべてのアクティブなセッションを解除します。
- UIの遅延はネットワークの遅延に続きます。 クリック、キーストローク、スクロールのたびにサーバーへの往復が行われているため、遅延の多いリンクを使うユーザーはアプリの動きが鈍く感じられます。
WebAssembly
インタラクティブコンポーネントはブラウザ上でコンパイルされた.NETコードとして動作します。サーバーの役割は、静的ファイルやフレームワークのHTTP APIエンドポイントを /api/auth/* と /api/*で提供することに縮小されます。
- ステートレスサーバー。 ホストはスティッキーセッションがなく水平方向にスケールし、再起動しても目に見える障害はなく、サーバーのユーザーあたりのメモリコストはほぼゼロです。
- キビキビしたUI。 ほとんどのやり取りはブラウザ内で行われ、クリックごとにSignalRの往復は行われないため、バンドルが読み込まれるとアプリは即座に感じられます。
- オフライン対応。 ロードされたポータルは、ネットワークが切断されてもキャッシュデータに対してレンダリングと検証を続け、戻るとAPIと同期します。
トレードオフ:
- 初回ダウンロード。 .NETランタイム、フレームワークアセンブリ、ポータルのコードは初読み時にブラウザに届きます(圧縮され、多くの場合数MBです)。その後の訪問はブラウザのキャッシュから読み込みます。
- APIサーフェスが必要です。 UIがサーバーから求めるものはすべてHTTPエンドポイントとして公開しなければなりません。Power Portals Proは、データおよび認証エンドポイントを標準で提供します。カスタムサーバーロジックには独自のコントローラーや最小限APIエンドポイントが必要です。
- ブラウザ側のパフォーマンス。 CPU負荷の高い作業(大規模なグリッドや複雑なチャート計算)はWebAssemblyの速度で動作し、これは高速ですが、ネイティブのサーバーサイド.NETよりは遅いです。
自動車
最初のペイントはサーバーから来るため(ユーザーがすぐにコンテンツを見られます)、クライアントバンドルのダウンロードが終わるとランタイムは透明にWebAssemblyに切り替わります。Auto = サーバーが先に、その後WebAssemblyが同じルート上に行われます。
- 最高の知覚負荷+最高の定常状態ユーザー体験。 ユーザーはWASMバンドルを待つことなく即座に最初のペイントを手に入れ、その後ブラウザにランタイムがキャッシュされるとWebAssemblyのスキッとした操作を楽しめます。
- 単発の展開です。 ホスト1台、公開ステップ1回、WebAssemblyと同じで、サーバーランタイムがプリレンダーに持ち込まれます。
トレードオフ:
- 最も複雑なプロジェクトのレイアウト。 両方のランタイムは配線が必要です。コンポーネントはどちらかのレンダラーで正しく動作しなければなりません(共有コンポーネントにサーバー専用サービスを注入してはいけません)。
- サーバーレンダリングされた短いウィンドウ。 初回訪問時はWASMの交換が完了するまでサーバー側にレンダリングされます。Power Portals Proのテンプレートはこの移行をロードオーバーレイで隠し、中間状態はユーザーに見えません。
ヒント
このドキュメントサイトはオートモードで動作します。ブラウザの開発ツールのネットワークタブを最初の読み込み時に開くと、サーバーレンダリングされたHTMLが最初に到着し、その後WASMバンドルストリームが1〜2秒で到着します。その後、HTMLのナビゲーションはサーバーに届かなくなります。
どちらを選ぶか
特定の制約がない場合の大まかな目安:
- ポータルが同時利用者が少なかったり、企業ネットワーク内で安定した接続ができている場合、あるいはチームがBlazor初心者で最もシンプルなメンタルモデルを求める場合はサーバーを選びましょう。
- WebAssemblyを選んでも、ポータルが顧客対応で高い同時開時間、ホスティング料金がアクティブなセッション数に応じて増加する、またはオフラインでの動作が必要な場合などです。初回ダウンロード費用は訪問者一人あたり一度きりのヒットとして受け入れてください。
- バンドルダウンロードの初回塗装遅延を払わずにWebAssemblyの安定状態を望むなら、Autoを選んでください。ほとんどの生産ポータルはここに集まります。
チートシート
3つのモード間でファイルごとに何が変わるのか。生成されたプロジェクトとテンプレートを比較したり、手動切り替え後に不一致を追いかける際にこれを参考にしてください。
プロジェクトレイアウト
これら3つのモードは、サーバーホストプロジェクトと兄弟 .Client プロジェクトの両方を生成します。違いは .ClientのSDKと、それが実際にWebAssemblyバンドルにコンパイルされているかどうかです。
- サーバー —
.ClientMicrosoft.NET.Sdk.Razorを使います。共有コンポーネントを保持するクラスライブラリですが、WASMとしては公開されていません。 - WebAssembly —
.Clientは独自のProgram.csを持つMicrosoft.NET.Sdk.BlazorWebAssemblyを使用し、ダウンロード可能なバンドルにコンパイルされています。 - Auto — WebAssemblyと同じ
Microsoft.NET.Sdk.BlazorWebAssembly独自のProgram.csを持っています。
.csproj の違い
.ClientプロジェクトのSDKは変更され、WebAssembly専用のフレームワークパッケージはホストが実際にWASMを実行している場合にのみ表示されます。
<!-- サーバー専用: 。クライアントはRazorクラスライブラリです -->
<Project Sdk="Microsoft.NET.Sdk.Razor">
<!-- WebAssemblyまたはAuto:クライアントはBlazor WebAssemblyアプリです -->
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
WebAssemblyやAutoが有効な場合の追加パッケージ参照:
<!-- サーバーホスト(.csproj)— WebAssemblyまたはAutoの場合のみ -->
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
<!-- .クライアント(.csproj) — WebAssemblyまたはAutoの場合のみ -->
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" />
<PackageReference Include="PowerPortalsPro.Web.Client" />
サーバー Program.cs — サービス登録
AddRazorComponents() どのビルダーメソッドが連結されているかに基づいて、適切なレンダーモードコンポーネントペアを取得します:
// サーバー専用
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// WebAssemblyのみ
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
// オート(両方)
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
サーバー Program.cs — エンドポイントマッピング
MapRazorComponents<App>() 一致するレンダーモードのエンドポイントを連鎖します:
// サーバー専用
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddAdditionalAssemblies(typeof(MyApp.Client._Imports).Assembly);
// WebAssemblyのみ
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(MyApp.Client._Imports).Assembly);
// オート(両方)
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(MyApp.Client._Imports).Assembly);
App.razor — Per-Route Render Policy
App.razorのPageRenderModeゲッターは、各ルートがどのレンダラーを使うかを決定します。サーバーホストはどこでもサーバーを戻します。WebAssemblyとAutoホストは、WASMのみのIAuthServiceが解決されるように/Account/*ルートを明示的にピン留めする必要があります:
// サーバー専用 — App.razorのPageRenderMode
return new InteractiveServerRenderMode();
// WebAssemblyのみ — /Account/* をプリレンダーなしにピン留めしてIAuthServiceが解決できるようにします
if (HttpContext.Request.Path.StartsWithSegments("/Account"))
return new InteractiveWebAssemblyRenderMode(prerender: false);
return new InteractiveWebAssemblyRenderMode();
// 自動 — 同じ /account/* ピン、その他は自動
if (HttpContext.Request.Path.StartsWithSegments("/Account"))
return new InteractiveWebAssemblyRenderMode(prerender: false);
return new InteractiveAutoRenderMode();
なぜ/account/*が固定されているのか
Autoの最初のペイントはサーバーレンダラーの下で動作しますが、アカウントページの
IAuthServiceはWASMクライアントのDIグラフにのみ登録されています。明示的なピンでInteractiveWebAssemblyRenderMode(prerender: false)がなければ、オートホストはコールドセッションのプリレンダーで[Inject] IAuthServiceを解決できません。prerender: falseサーバー側のプリレンダーステップを完全にスキップするため、ページはWASMランタイムで一度だけレンダリングされます。
.クライアント/Program.cs — インタラクティブな場合のみ
サーバー専用ホストには .Client/Program.cs が全くありません(Razorクラスのライブラリ .Client )。WebAssemblyやAutoホストには、WASMランタイムの設定、クッキー認証転送で HttpClient を登録し、Power Portals ProのWASMクライアントサービスを登録し、起動時にクロスカッティングローカリゼーションをプリフェッチするファイルが含まれています。
// .クライアント/Program.cs — WebAssemblyとAutoのみに存在します
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddFluentUIComponents();
builder.Services.AddSingleton<CookieCredentialsHandler>();
builder.Services.AddHttpClient("PowerPortalsPro", client =>
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<CookieCredentialsHandler>();
builder.Services.AddSingleton(sp =>
sp.GetRequiredService<IHttpClientFactory>().CreateClient("PowerPortalsPro"));
builder.Services.AddPowerPortalsProWebClient();
var app = builder.Build();
await app.UserPowerPortalsProWebClient(
LocalizationBaselines.Default.Concat(new[] { "app" }).ToArray());
await app.RunAsync();
アイデンティティ/アカウントページ
Power Portals Proは、それぞれのレンダリングコンテキストごとに2つの並列したアカウントページセットを出荷しています。どのセットがプロジェクトに含まれているかはホストのモードによって異なります:
- サーバー —
UserManagerを直接使ってComponents/Account/Pages/下にサーバーレンダリングされたRazorページ。app.MapAdditionalIdentityEndpoints()を通じて登録されたフォーム・ポストエンドポイント。 - WebAssembly / Auto — フレームワークの
IAuthServiceラッパーを使ったインタラクティブなページ.Client/Pages/Account/。app.MapAuthEndpoints<PortalUser>()で登録されたJSONエンドポイントは、ログイン、登録、管理/*、外部ログイン完了をapplication/json呼び出しとして処理します。
// サーバー専用 — サーバーレンダリングされたアカウントページで使用されるフォームポストのアイデンティティエンドポイント
app.MapAdditionalIdentityEndpoints();
// WebAssemblyまたはAuto — JSON /api/auth/* エンドポイントが使用します。クライアントのIAuthService
app.MapAuthEndpoints<PortalUser>();
今後のステップ
すでにあるモードでプロジェクトを持っていて別のモードに変換したい場合は、ファイルごとの変更については Switch Blazorのインタラクティブ ページをご覧ください。
