Blazor WebApp을 프로젝트를 생성,
@rendermode의 차이를 경험해보고 싶었으나, 여러 제약사항들 걸리면서 개념을 정리해보기로 했다.
렌더링 방식은 총 4가지
@rendermode 미지정 - Static SSR - 정적 서버렌더링 대화형 X
@rendermode InteractiveServer - 대화형 SSR
@rendermode InteractiveWebAssembly - 대화형 CSR
@rendermode InteractiveAuto - 대화형 SSR+CSR (번들 다운로드 상태에 따라, 자동)
CSR을 사용하기 위해서는 별도의 Client프로젝트(WebAssemblyHost 사용) 구성하여야 한다.
Client프로젝트는 wasm으로 빌드되어, 클라이언트에게 전달되어 CSR이 되는 방식, 고로 CSR을 사용하려는 모든 페이지는 해당 프로젝트에 있어야 함.
제약사항
1. 이벤트 처리
Static SSR은 정적페이지이며, @onclick같은 이벤트 처리를 할 수 없다.
2. 브라우저 접근
모든 대화형 렌더링은 기본적으로 서버에서 렌더링되는 시점에 브라우저에 접근할 수 없으므로, 관련 기능을 사용할 수가 없다. (SSR만의 이슈가 아니라, CSR도 동일하다.)
이것에 대한 해결방안은
첫번째로 InteractiveServerRenderMode(prerender: false)로 설정하여, ProtectedLocalStorage나 ProtectedSessionStorage를 OnInitialized에서 사용이 가능하나, Blazored.LocalStorage 패키지는 불가능 하다.
같은 이슈로 JSInterop 사용은 OnAfterRender 이후에 가능하다. (OnInitialized 호출시점에 사용불가)
참고로 StandAlone WebAssembly에서는 가능함
두번째로 Router 컴포넌트를 감싸는 Provider를 만들어, OnAfterRender 이후에 자식을 렌더링 시키는 방법
라우팅 이전에 브라우저 접근이 가능한 상태까지 렌더링 한 후, 자식을 렌더링하므로써, 자식들은 JSInterop과 LocalStorage를 사용할 수 있다.
LocalStorageProvider.cs
@inject ILogger<LocalStorageProvider> _logger
@inject IJSRuntime JsRuntime
@if (isLoaded)
{
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
}
else
{
<p>Loading...</p>
}
@code {
private bool isLoaded;
[Parameter]
public RenderFragment? ChildContent { get; set; }
[CascadingParameter]
private HttpContext? HttpContext { get; set; } // Only during pre-render will it not be null.
protected override async Task OnInitializedAsync()
{
_logger.LogInformation($"OnInitialized() is pre-render: {HttpContext is null}");
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
_logger.LogInformation($"OnAfterRenderAsync() firstRender: {firstRender}");
if (firstRender)
{
await JsRuntime.InvokeVoidAsync("Loaded"); // JS 호출
isLoaded = true;
StateHasChanged();
}
}
}
위 방법은, App.razor에서부터 콤포넌트에 @rendermode InteractiveServer를 사용하여야, 정상적인 상태적용이 가능하다.
(이렇게 되면 전체 @rendermode가 InteractiveServer로 변경되므로, SSR 사용이 강제됨)
(SSR 사용이 강제되므로써, 인증처리 또한, 서버를 통해 구성되어야 한다.)
3. 트래픽
브라우저 기능을 버리고(렌더링 이후에 사용하고), 대화형 CSR을 사용하거나, InteractiveAuto를 구성을 한다고 해도,
수십 MB에 이르는 wasm을 서버에서 내려주어야 하므로, 트래픽 또한 상당하다.
static 형태인 WebAssembly는 단순 웹서버 혹은 CDN 등을 통해서 배포가 가능한 반면,
Blazor WebApp은 서버를 통해야만 모든 처리를 할수 있기에, 배포 또한 고려하여야 한다.
결론
CSR+SSR을 우아하게 사용할 수 있을 거란 기대는 산산조각 나버렸다.
의아한 부분이다.
가능하지만 너무나 까다롭다.
단순 정적페이지로 구성된 Viewer사이트수준에서나 가능한 느낌,
빛좋은 개살구인가??