Blazorファーストルック

(An [English version of this article](https://www.linkedin.com/pulse/blazor-first-look-hideki-saito/) is also available.)

この記事ではMicrosoftにより開発された[Blazor](https://blazor.net)に関して説明していきます。Blazorのプログラミング方法というよりはその用途など、ハイレベルな部分を紹介していきたいと思います。

# Blazorとは
BlazorはMicrosoftにより開発された、シングルページアプリケーション（SPA）を作成するためのフレームワークです。
.NETの機能を使うことにより、C#でウェブアプリケーションを開発することができます。
現在、Blazorには二種類あります。

* Blazor Server
* Blazor Client (WebAssembly)

この記事ではその二種類を合わせて見ていきます。

# 二種類のBlazor
さて、Blazorには二種類あるわけですが、その特徴を見ていきます。

## 共通する部分
* C#を使用して記述。
* 多くの既存の.NETコードがそのまま動作。（環境ごとの差異に関しては後述を参照してください。）
    * 多くの[NuGet](https://www.nuget.org/)パッケージも使用できる。
* テンプレートはRazor。
* ファイル構造上は両方とも非常に近い。（Previewの段階では異なる部分も多かったが、ある程度共通化された。）
* JavaScriptとの連携が可能で、これはJSRuntime機構を使用し、双方向とも連携が可能。
    * 特にDOM操作などの場合に使用。

## Server
* プログラムはサーバー上で動作。ブラウザはシンクライアントに徹する。
* コミュニケーションはSignalR経由で行われる。（SignalRが使えない場合のフォールバック有り）
* 要はサーバサイドレンダリング。
* ベースは[.NET Core](https://dotnet.microsoft.com/)

![Blazor Server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80859/f1a16a5b-6fb9-735d-663f-3b26397ed59a.png)

## Client (WebAssembly)
* プログラムはブラウザ上で動作。WebAssemblyにより、.NETプログラムをそのままブラウザ上で実行。
    * なので、サーバーは静的サイトでも問題なし。
* ベースは[Mono](https://www.mono-project.com/)、具体的にはnetstandard2.1ベース。

![Blazor Client.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80859/879b0083-0bce-9dc7-1dd9-504f31e08533.png)


# 簡潔な使い方

Blazorを使用するのには.Net Coreが必要です。Blazor Server、Blazor Client両方を使えるようにするためには3.1.300以上を入手します。

この上で、新しいプロジェクトを作成できます。

Blazor Serverの場合は新しいディレクトリ上で以下のように作成できます。

```
dotnet new blazorserver
```

Blazor Clientの場合は以下の通りです。

```
dotnet new blazorwasm
```

いずれの場合も、新ディレクトリ上で次のように実行すると実際に走らせてみることができます。

```
dotnet run
```

開発中にホットリロードのような形で自動更新したい場合は以下のようにも実行できます。

```
dotnet watch run
```

# プログラミングの特徴

詳しいプログラミング方法に関しては公式ドキュメントなどで解説されていますので、軽く触れるぐらいに留めますが、内容的にはReactなどでも使用されるコンポーネントベースの構造に近いものになっています。

以下は<code>dotnet new</code>で得られるサンプルコードの内容になります。

```csharp
@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}
```
尚、コンポーネントとして新しいタグを定義することもできます。プロパティはC#のアノテーション機能を使用して定義します。

```csharp
@using Microsoft.AspNetCore.Components
<div>
    Hello, @Person
</div>

@code
{
    [Parameter]
    private string Person { get; set; }
}
```

この場合、次のように使用できます。

```csharp
<Hello Person="my friend">
```


# 利点と欠点

## Blazor Server
### 利点
* フルセットの.NET Coreライブラリを回せるため既存の.NET Coreコードがそのまま利用できる。
* ブラウザのサンドボックスの影響を受けない。
* サーバークライアント間の通信は軽量。起動時間は非常に短い。
* サーバー側のファイルシステムのファイルにそのままアクセスできる。
* 古いブラウザに対してもpolyfillで対応できる可能性があり。
* Visual StudioやVisual Studio Codeでサーバ側のプログラムにブレークポイントを設置することで通常の.NET Coreのアプリケーション同様のデバッグが可能。

### 欠点
* 動的に.NET Coreのプログラムを実行できるバックエンドが必要になる。（尚、.NET Coreには[Kestrel](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel)というサーバーが用意されているため、これにリバースプロキシをかける方法がいいかと思います。<code>dotnet run</code>で実行されるのはこのサーバーです。）
* SignalRの構造上、セッションごとのリソースの確保が必要になってくる。
* UIの変化の都度、通信が発生する構造であるため、ネットワークレイテンシーの影響がある。

## Blazor Client
### 利点
* .NET Standardに対応する多くのライブラリがそのまま利用できる。
* プログラムはブラウザ上で実行されるため、ネットワークレイテンシーの影響を受けない。
* サーバー側の対応はほとんど必要なく、静的サイトが置けるサイトで十分。
* Chrome/Edge、もしくはVisual Studio Codeを使用してのデバッグが可能。

### 欠点
* ブラウザにWebAssemblyの対応が必須となるため、古いブラウザで実行できないものがある。
* ブラウザーのサンドボックスの影響を受けるため、ファイルのアクセスなどはできず、<code>Http.GetFromJsonAsync</code>などの方法でデータを取得する必要がある。（CORSの影響も受ける）
* スレッディングの対応がないため、並列実行などの処理には向かない。（ただし、これはBlazorの問題というよりは、ブラウザの仕様に起因するものであり、Service Workersなどを使用することにより解決できるかと思われます。尚、Blazorにおいても、[BlazorWorker](https://github.com/Tewr/BlazorWorker)などの実装があります。）
* ライブラリ対応が.NET Coreにターゲットされているものよりは少なめ、Blazor Serverが使用できるものに比べると使用できるものが少なくなる。
    * もっともNuGetで配布されているパッケージは近年では.NET Framework/.NET Core間での互換性を持たせるため、.NET Standardに対応しているものが多くなってきている。
    * また、.NET Standardライブラリであってもブラウザ環境を前提をしたものでない場合も多い（ファイルのアクセスを前提にしているなど）ため、調整が必要になってくる。
* .NETライブラリを転送する必要があるため、初期開始のスタートアップは遅め。
    * 二回目移行はキャッシュされていれば、速くなる。
    * 転送量は使用しているライブラリにもよるが1.5MB以上。

# まとめ
Blazor Serverに関してはサーバ環境がある程度必要になってくる点や、またSignalRを使用したサーバサイドレンダリング環境であり、レイテンシーの影響を受けやすい、というような点から、ユーザーやネットワーク環境が想定しやすいエンタープライズ環境で使用しやすい仕組みかと思います。

既存の.NET資産を使用し、他のエンタープライズシステムなどへのアクセスとの連携が可能であるという点、またアクセスキーなどのセンシティブな情報をサーバサイドにとどめておけるという点において、そういったニーズがある場合、Blazor Server一択になるかと思います。

対して、Blazor Clientはクライアント側で完結できるシステムや、また、比較的オープンなシステムにアクセスするためのシステム、提供元を選ばない、という特性上、不特定多数に対して提供するサービスに向いている構造かと思います。Reactなどの代わり、ということであればこちらが本命になるかと思います。

どちらも比較的新しいシステムであり、現状、ドキュメントなど、広くは存在していないのが現状かと思いますが、C#を使用し、比較的少ないJavaScriptでの記述でウェブアプリケーションが開発できるという特性上、生産性は非常に高く、今後の普及、発展に期待したいところです。

# おまけ
いくつかBlazor Clientで作ったアプリケーションを公開していますので紹介しておきます。

* [HSTempoWasm](https://hstempo.hidekisaito.com/)
* [仙狐ビュワー](https://senko.hidekisaito.com/)