Blazorを選ぶ基準はこれだ！

## 選定基準

選定基準は、チームの技術スタックにほぼ100%依存します。

もし、あなたのチームの技術スタックが、、

- **Asp.Net系のみ** => **Blazor**を選択してください

    単純に学習コストの問題です。JavaScript(TypeScript)のSyntaxに慣れるのがかなり大変なようです。また、使い慣れたVisual Studioで開発できるというのもポイントです。

    ただし、状況によってはJavaScriptで補完する箇所も出てくるので、バランス感覚が重要です。

    調査は骨が折れます。最近のUpdateにエコシステムがついてこれていないように見えます。
    
<br/>

- **JavaScript系のみ** => **JavaScript**を選択してください

    Browser上で、**Blazorでできないことがあっても、JavaScriptでできないことはない**からです。

    例えば、モーダルコンポーネントで背面のスクロールを無効にしたい場合、Blazorでは、`body`エレメントを直接操作できず、JavaScript経由で操作することになります。

    また、文献含むエコシステムが圧倒的に多いです。だいたい同じ悩みを持った人を見つけることができます。
    

<br/>

- **どちらも持っている** => **JavaScript**を選択してください

    エコシステムが圧倒的だからです。メンバーも採用しやすいです。
    
<br/>

- **どちらも持っていない** => **JavaScript**を選択してください

    学習コストはかかる前提で、Asp.Netよりは低いと思います。私の好みもありますが、Asp.Netのドキュメントは中々頭に入ってきません。

    豊富なエコシステムにより、チュートリアル関連も多いです。


<br/>

`if( Asp.Net && !JavaScript ) decide(Blazor) else decide(JavaScript)`ですね。

Blazorを選択した場合、以下に記載の特徴をしっかりと理解しておく必要があります。

私はNext.Jsを主に扱っているのですが、Next.JsのSSR(Server Component)とは全く異なるもので、これらの特徴を理解するのに骨が折れました。

## Blazorの特徴

### [Render mode](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0#render-modes)

BlazorはComponentごとに`Rendering mode`を持つことができ、それぞれ以下のようになっています。特に、`Interactive Server`は、**デプロイ環境の選定にまで影響します。**

- Static Server

  静的なComponentで、`razor`ファイル内の`@code`内で設定したボタンクリックイベント等は無効になります。
  
  コンパイルエラーにはなりませんが、Browserでページを表示してボタンを押下しても何も反応しません。
  ただし、`<script></script>`で作成したJavaScriptをコールすることは可能です。単純にHtml + JavaScriptの組み合わせでロードされるので当然といえば当然ですね。
  
  Formイベントにも対応しており、`EditForm`を用いたバリデーション、Submitは可能となっています。

  明示的に指定しない限り、`Static Server`が**デフォルト**のRender modeになります。

  <br/>

- Interactive Server

    Dynamic Serverではないことをよく注意してください。従来のSSRのような、ページリクエストに応じて動的にページを生成するものではありません。

    このモードで動くComponentは、BrowserサイドからHtmlイベントの通知を受け取り、**ServerサイドでUIをレンダリング**して、差分更新をBrowserに通知し、それをBrowserが再描画します。
  
    つまり、Serverサイドは**Statefull**で、相互的な通信を許可する状態でなければいけません。Blazorでは、`SignalR`というWebSocketベースのプロトコルで相互通信を実現します。

    ということは、デプロイ環境でロードバランサーを使うときは、**`Stickey Session`**が必須です。更に、Serverサイドも`AWS Fargate`などの**サーバーレスではダメ**で、Stateを維持できるServerを配置することが必要になります。

    ちなみに、ServerサイドのStateは`Circuit`と呼ばれ、チュートリアルプログラムレベルでも、1`Circuit`で400KBほどメモリを占有するらしいです。
  `Circuit`は、Browserのタブごとに生成されるので、例えば、私が5タブで同じアプリケーションを開いていても、5`Circuit`がしっかり消費されます。

<br/>

- Interactive WebAssembly
    WebAssemblyを利用したBrowserサイドでの描画になります。Browserでイベント処理が行われ、描画がおこなわれます。
    
    一般的なCSRです。`Interactive Server`が特徴的過ぎですね。

<br/>

- Interactive Auto
    これは、`Interactive Server`と`Interactive WebAssembly`を自動で設定するもので、状況に応じて選択されます。

    初回リクエストでは、`Interactive Server`としてレンダリングが行われますが、2回目以降は、`Interactive WebAssembly`として動作します。これは、キャッシュやBrowserへのRuntime到着などにより左右されます。

    これも`Interactive Server`が関わってくるので、上述したデプロイ環境の制約を受けてしまいます。


### [Prerendering](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0#prerendering)と[Lifecycleイベント](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-8.0#lifecycle-events)

ここもNext.Js脳では全く理解できなかったところなので、ご紹介します

`razor`コンポーネントは、レンダリングの度にLifecycleメソッドと呼ばれる様々な一連の処理がServerサイドで走ります。この処理は、Prerenderフェーズでも実行されます。

なんと、`Static Server`や`Interactive WebAssembly`といったServerサイドが全く関係なさそうなRender Modeでも実行されます。

ちなみに、以下のように記載するとPrerenderを抑制することができます。

```c#:component.razor
@page "/"
@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))

<div>Component</div>

@code {}
```


## 最後に

Blazorでも、ReactでいうProviderや、Next.jsのLayout、Reduxのような状態管理の仕組みは存在しており、FWの機能を使って便利なことができる点は良いと思います。

Microsoftが激押ししているのも納得のフレームワークですね。

もし時間的な余裕があるのであれば、POCでしっかりめのアプリケーションをBlazorで作ってみることをお勧めします。



※これはAsp.Net Core 8.0時の記事です。