Blazor WebAssembly を Azure Blob Storage でホストする

この記事は更新から24ヶ月以上経過しているため、最新の情報を別途確認することを推奨いたします。

はじめに

Blazor とは、C# (.NET Core) でクライアント側 UI を構築するためのフレームワークです。

主要なブラウザーでサポートされており、JavaScript を記述することなくクライアント側の処理を実行できます。

またサーバー側・クライアント側ともに . NET で記述することでロジックの共有や既存の .NET ライブラリを活用できるといった利点があります。

 

端的に言って、Blazor がささるひとは C#er でしょう。MVC + Bootstrap テンプレートが主だったり、あまり JavaScript やフロントエンドを書かない C#er にとっては、C# ひとつでモダンなフロントエンドを構築できる可能性を秘めています。

 

この記事では、Blazor サーバーではなく SPA として今後主流になるであろう Blazor WebAssembly を作成し、Azure Blob ストレージにてホストしてみます。

 

Blazor ホスティングモデル

Blazor には、Blazor WebAssembly (2020年5月に GA 見込み) と Blazor サーバー (GA) の2種類のホスティングモデルがあります。

ASP.NET Core サーバーの要不要等の違いなど、ホスティングモデルの違いを見ていきましょう。

Blazor WebAssembly

Blazor WebAssembly では、アプリの実体や依存関係、.NET ランタイムが DLL としてブラウザーにダウンロードされ、ブラウザーの UI スレッド上で直接実行されます。

また、アプリは静的ファイルとして生成されるため、Azure Blob ストレージなど静的コンテンツをホストするサービスや Web サーバーにて展開できます

 

利点として以下の点などあります。

  • アプリをクライアントにて処理するためサーバーの負荷が軽減される
  • クライアント側にアプリをダウンロードすれば使える

欠点として以下の点などあります。

  • アプリのダウンロードサイズが大きくなる
  • アプリの読み込みに時間がかかる
  • デバッグには制限がある

Blazor サーバー

Blazor アプリは、ASP.NET Core アプリ内からサーバー上で実行されます。UI の更新、イベント処理、JavaScript の呼び出しは、SignalR 接続経由で処理されます。

例えば UI の更新は、ボタンの選択などユーザー操作やタイマー等がトリガーとなってサーバーに伝播し、UI の差分がバイナリ形式でクライアントに送信されブラウザーにて適用されます。

 

利点として以下の点などあります。

  • ダウンロードサイズが WebAssembly よりも大幅に小さい
  • .NET Core と互換性のある API の連携などサーバーの機能を最大限に活用できる
  • デバッグが容易
  • アプリのコードがクライアントに隠蔽される

欠点として以下の点などあります。

  • 待機時間が長くなる (すべてのユーザー操作にネットワークIOが発生)
  • オフラインで動作しない
  • 多数のユーザーがいるアプリでスケーラビリティが困難
  • ASP.NET Core サーバーが必要となる

Blazor WebAssembly を作成する

プロジェクトを作成する

Visual Studio 2019 では現状のままですと Blazor WebAssembly のテンプレートがなく作成できません。

チュートリアルに従い .NET Core 3.1 SDK をインストールしたあと、以下のコマンドを打ち込みます。

dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.1.0-preview4.19579.2

dotnet new blazorwasm

ひとつめで Blazor WebAssembly のテンプレートをインストール、ふたつめでコマンドラインのカレントフォルダーに Blazor WebAssembly のプロジェクトを作成します。

また、テンプレートをインストール後は Visual Studio 2019 でもBlazor WebAssembly テンプレートが選択できるようになっています。

Todoリストを追加する

テンプレートそのままではなく Todoリストを追加してみます。こちらもチュートリアルを参考にしていきます。

Pages フォルダーに Todo.razor を追加して以下を記載します。

@page "/Todo"

<h1>Todoリスト 残り:@todos.Count(todo => !todo.IsDone)</h1>

<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>

<input placeholder="やること" @bind="newTodo" />
<button @onclick="AddTodo">追加する</button>

@code {
private IList<TodoItem> todos = new List<TodoItem>();
private string newTodo;

private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}

上記では、ひとつの razor ファイルに UI と処理を記載しています。また、別の razor ファイルに既存の razor ファイルを入れ子として記載することも可能です。

気をつけるところとして、razor ファイル名 (コンポーネント名) は大文字で始まらないといけない規則があるようです。todo.razor にすると、以下のようなエラーが発生します。

Component 'todo' starts with a lowercase character. Component names cannot start with a lowercase character.

 

Azure Blob ストレージにホストする

作成したアプリをファイルとして発行し、生成されたファイルを Blob ストレージに配置すると、以下のようにホストできました。

C# なのに静的ファイルとして動作し、且つクライアントサイドで UI が更新されることが確認できました。

なお、WebAssembly の DLL はダウンロードすればデコンパイルツールによって中身は確認可能です。センシティブな情報は記載しないようにしましょう。

 

まとめ

優秀なフロントエンドのフレームワークが多数ある昨今、メジャーになるかはさておき Blazor は C#er にとって可能性を秘めています。

とくに C# で動作するアプリを Web 上に持っていきたい要件があれば検討に値するのではないでしょうか。

 

また Blazor の次の展開として Webアプリだけでなく、プログレッシブ Web アプリ (Blazor PWA)、Electron のようなハイブリッドアプリ (Blazor Hybrid)、さらにデバイス毎のネイティブコントロールに対応したネイティブなアプリ (Blazor Native) も今後サポートされる予定です (前者2つは2020年11月にプレビュー予定)。

Silverlight と同じ道をたどるかは不明ですが、C#er にとっては引き続き注視していきたい技術です。

Blazor Server in .NET Core 3.0 scenarios and performance

現在パーソルプロセス&テクノロジーではAdvent Calendar 2019を開催中です。
https://qiita.com/advent-calendar/2019/ppt
こちらも興味ある記事あれば是非ご参照ください。

いいね (この記事が参考になった人の数:13)
(↑参考になった場合はハートマークを押して評価お願いします)
読み込み中...

注意事項・免責事項

※技術情報につきましては投稿日時点の情報となります。投稿日以降に仕様等が変更されていることがありますのでご了承ください。

※公式な技術情報の紹介の他、当社による検証結果および経験に基づく独自の見解が含まれている場合がございます。

※これらの技術情報によって被ったいかなる損害についても、当社は一切責任を負わないものといたします。十分な確認・検証の上、ご活用お願いたします。

※当サイトはマイクロソフト社によるサポートページではございません。パーソルクロステクノロジー株式会社が運営しているサイトのため、マイクロソフト社によるサポートを希望される方は適切な問い合わせ先にご確認ください。
 【重要】マイクロソフト社のサポートをお求めの方は、問い合わせ窓口をご確認ください