Blazor web app 이란 무엇인가? (dotnet 8)

2023. 12. 4. 00:00ASPNET/Blazor

반응형

dotnet 8 에 주요 골자는 blazor 였다고 생각된다.

aspnet 진영에 많은 부분은 결국 blazor 가 주가 되었다. 

 

여기서는 dotnet 8 에서 blazor 의 최신 추가내용을 직접 작성해 보며 알아보겠다.

 

Visual Studio 2022 를 설치했다고 가정하겠다. (17.8 이상버전)

 

Blazor web app 을 선택 해서 들어간 후 아래와 같이 설정하자

그리고 create 를 한 후 solution 의 구성을 확인해 보자 

 

두개의 project 가 생성되는데 위쪽은 SSR 을 위한 server 쪽 이라고 생각하면 쉽고

아래 쪽은 CSR 을 위한 webassembly 영역이라고 생각하면 쉽게 이해할 수 있을 것이다. 

 

blazor 의 새기능은 auto rendering 으로 요약할 수 있는데

이것은 SSR 와 CSR 의 장점을 통합했다고 할 수 있다. 

 

SSR 은 초기 page 의 loading 은 빠른 편 이지만 Server 와의 계속된 네트워크 작업으로 인해

빠른 반응이 필요한 app 에는 적합하지 않았다. 

그래서 websocket 같은 realtime app 이 필요해 지기도 했다. 

 

CSR 은 Client 에서 page 의 control 을 담당하다 보니 네트워크 작업이 없다. (거의 없다.!!)

그러다 보니 빠른 반응이 필요한  app 에는 적합하다. 

하지만 초기 loading 이 느린 편(??) 이어서 자주 변경되는 app 이라면 다시 download 하는 시간이 많아 적합하지 않다.

 

이러한 문제들을 해결하기 위해 Blazor 을 auto render mode 라는 것을 만들었다. 

 

이 모드는 다음과 같이 작동한다. 

1. 초기 loading (web assembly) 이 안된 상태라면 SSR 로 작동한다.  

2. 초기 loading 이 완료되면 그 이후 page 접속 부터는 web Assembly 를 통해 CSR 로 작동한다. 

 

이제 앞에서 이야기 했다. 두 모드의 장점은 수용하고 단점은 최소화 되었다. 

 

MS 에서 심혈을 기울여서 이 Blazor 에 집중하고 있다고 보인다. 

 

참조 : https://chrissainty.com/blazor-in-dotnet-8-full-stack-web-ui/images/render-modes-auto.png

 

 

 

자 그럼 이 프로젝트를 조금 분석해 보자

두개의 프로젝트가 있는 이유가 있다. 

blazor 는 server 호스팅 모델과 webassembly 를 이용한 client 호스팅 모델이 있다. 

(전통적인 SSR , CSR 과는 조금 다르다.)

 

Server 호스팅 모델은 초기에 page 에 접속하면 SignalR 을 이용해서 websocket 을 연결하고

이것을 이용하여 page 의 변경사항을 적용한다. 

즉 page 전체를 refresh 하지 않는다.

그래서 서버로 부터 rendering 을 하면서도 좀더 빠른 성능이 가능한다. 

 

WebAssembly 는 spa 에 대응 되는데 server 를 전혀 거치지 않기 때문에

위 Server 호스팅 모델에 비해 좀더 빠른 성능을 보인다. 

 

어쨌든 이 두 모델을 하나의 솔루션에 모아 놓은 것이다. 

StepOne 이 Server, StepOne.Client 가 WebAssembly 이다. 

 

일단 실행해 보면서 각 구조를 알아보자 

위와 같이 간단한 화면이 뜬다. 이 상황에서 devtools 를 확인해보면 아래와 같을 것이다.

(초기에 devtool 을 먼저 뛰워놓고 페이지로 이동하자)

뭐 여러가지들이 있는데 지금 다 알필요는 없고 websocket 만 확인하자

이 페이지가 server hosting 모델로 실행된다는 걸 알수 있다. 

 

이제 Weather page 로 이동해 보자 

 

초기에 저 화면이 잠깐 스쳐지나갈 것이다. Loading...

그리고 위 화면이 표시된다. 

자 이제 이 화면에 어떤 마술이 있는지 페이지로 이동해 보자

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                
                ...
protected override async Task OnInitializedAsync()
{
    // Simulate asynchronous loading to demonstrate streaming rendering
    await Task.Delay(500);

    var startDate = DateOnly.FromDateTime(DateTime.Now);
    var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
    forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = startDate.AddDays(index),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = summaries[Random.Shared.Next(summaries.Length)]
    }).ToArray();
}

 

Weather.razor 에 내부에 위와 같이 if else 를 이용해서 Loading... 및 data 처리를 하고 있다. 

그리고 c# code 상에서 0.5 초를 대기한 후 (api 를 호출한것 같은 simulation)

Weather 를 표시하고 있다. 

그런데 web 을 조금 아시는 분들은 저코드가 정상 동작할리가 없다는 걸 알고 있다. 

왜냐하면 Loading 이라는 부분을 처리 하려면 page 전체에 영향을 주기 때문에

저부분만 따로 component 를 만들거나 javascript 같은 걸로 show hide 같은 것을 해야한다.

 

자 이부분에서 blazor 가  몇가지 마술(?) 을 부린다. 

코드 상단에 아래와 같은 코드가 있을 것이다. 

 

@attribute [StreamRendering] <--- 이녀석이 저 마술을 부리는 녀석이다. 

 

Blazor 8 부터는 Rendering 모드가 몇몇 추가 되었고 개발자가 직접 제어 할 수 있게 되었다. 

이것은 project 전체에 적용가능 하기도 하고 page 마다 또는 component 마다 적용가능하기도 하다.

 

위 코드는 현재 page (weather) 에 Rendering mode 를 StreamRendering 으로 하겠다는 것이다. 

이코드는 꽤오랜 작업이 실행되는 page 에 유용하다고 볼수 있다. 

 

 

이제 client 쪽으로 이동해서 Counter 를 확인하자

 

자 이 component가 제일 중요한데 이유는 blazor 의 가장 진보된 기능이 있기 때문이다. 

다음과 같이 Counter.razor 를 수정하자

@page "/counter"
@rendermode InteractiveAuto
@inject IConfiguration config

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>
<p>
    @message
</p>

<p role="status">Current count: @currentCount</p>

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

@code {
    private int currentCount = 0;
    private string message = "";

    protected override void OnInitialized()
    {
        message = config.GetValue<string>("Message");
    }
    private void IncrementCount()
    {
        currentCount++;
    }
}

 

이제 Server 쪽 appsettings.json 을 수정하자 (client 가 아니다 )

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Message": "Hello" //<-- 이것 추가
}

 

이제 실행하고 counter 로 이동해 보자 

처음에는 위와 같이 Hello 가 표시 되지만

조금 시간이 지나면 Hello 는 사라진다...

데헿!! 이제 없지롱

 

이게 바로 rendering auto 모드에 마술이다. 

 

처음에 실행은 server 에서 실행이 되었고

조금 지나 (webassembly 가 download 가 완료되면) webassembly 모드로 동작한다. 

(일단 이부분은 확인이 필요한데 debug 모드에서만 저렇게 동작하고

production 에서는 page 의 이동이 일어나야만 저렇게 동작하는 걸로 보인다. )

 

어쨌든 저렇게 동작하는 이유는 아래 코드 때문이다. 

 

@rendermode InteractiveAuto

 

자 오늘은 일단 이렇게 간단하게 확인해 보고

다음시간에는 조금도 깊이있게 진행해보자

 

 

관련영상

https://youtu.be/obHZKDm6yog

반응형

'ASPNET > Blazor' 카테고리의 다른 글

Blazor Web App - Register and Login (Identity Server)  (0) 2023.12.18
Blazor Web App - 렌더링 개념  (1) 2023.12.11
이벤트 처리 2  (0) 2022.05.06
이벤트 처리  (0) 2022.05.05
Binding 3  (0) 2022.05.04