Blazor WebAssemblyでプリレンダリング

Blazor WebAssembly

このサイトはなぜかBlazor WebAssemblyで作られています。今のところこのサイトでBlazor WebAssemblyを使う技術的に正当な理由はたぶんありません。でも使ってます。将来的になにか理由ができることでしょう…

Blazor WebAssemblyは初回アクセス時に.NETランタイムなどをダウンロードしてくるため、初回のパフォーマンスがよろしくないという欠点があります。あと"ギガ"が大きくなります。このページをDeveloper Tools でのぞいてみると、(現時点では)初回は

2.1 MB が転送されました 5.1 MB 個のリソース

といった具合だと思います。たかがブログサイトにしてはなかなかのサイズです。ごめんちゃい。もちろんキャッシュはされます。

ローディングやめたい、あとSEO対策も一応したい

Blazor WebAssemblyのサイトにアクセスすると、通常最初はローディング画面が表示されます。.NETランタイムをダウンロードしてきてなんやかんやするまで待ってもらう必要があるためです。でもあんまりよい体験ではないです。また、Blazor WebAssemblyはいわゆるCSR(Client Side Rendering)なので、SEO的にはあまりよろしくないです。何も対策しないと、Googleなどのクローラーはローディング画面しか見れないことになります。

これに対するBlazorの一般的な解決策はサーバサイドを用意してStatic SSRするなりプリレンダリングするなりのようです。調べた限りでは。でもサーバサイドは用意したくないです。面倒くさい!

ビルド後にプリレンダリング

そこで、Blazor WebAssemblyをビルドした直後にプリレンダリングできたらいいじゃないと思いちょっと調べるとピッタリのものがあるじゃないですか。

jsakamoto/BlazorWasmPreRendering.Build: When you publish your Blazor Wasm app, this package pre-renders and saves the app as static HTML files in your public folder.

詳しくはREADMEを見てもらうとして、nugetパッケージ追加してすこ~し設定いじるだけでプリレンダリングしてくれるようになります。とくにWebAssemblyPrerenderedというモードを指定すると、単にhtmlを書きだすだけでなく、PersistentComponentStateも使えます。

<BlazorWasmPrerenderingMode>WebAssemblyPrerendered</BlazorWasmPrerenderingMode>

すごい。

Lighthouseのスコアも最終的にもうちょいで100点いけそうな感じになりました。やったね。

Lighthouseのスコア

パフォーマンスが92点止まりですが、どうしてもTBTを小さくできなかったです。これはBlazorを起動する限りはやはり避けられないんでしょうかね。

SSG

BlazorがSSG(Static Site Generation)に対応していたらSSGで作ってみるつもりだったんですがまだ対応されていません。一応BlazorStaticというプロジェクトもあるみたいですが、まだちょっと実験的な感じがしたのと、今回はBlazorを試すというのが(一応の)目的?だったので、プリレンダリングを使う構成にしてみました。構成はたぶんそのうち変わります。

BlazorそのものへのSSGの組み込みはBlazor static site generation support · Issue #55320 · dotnet/aspnetcoreというissueがあるので将来的にはやる…のかもしれません。やらないのかもしれません。対応されたらわたしのような初心者でもBlazorに手を出しやすくなるので良いと思うんですけどね。

An unhandled error has occurred. Reload 🗙