핵심 구성 요소 ASP.NET Razor 미리 렌더링
이 문서에서는 Razor 서버 렌더링 구성 요소의 구성 요소 미리 렌더링 시나리오에 Blazor Web App대해 설명합니다.
미리 렌더링 은 렌더링된 컨트롤에 대한 이벤트 처리기를 사용하도록 설정하지 않고 서버에서 페이지 콘텐츠를 처음 렌더링하는 프로세스입니다. 서버는 초기 요청에 대한 응답으로 가능한 한 빨리 페이지의 HTML UI를 출력하므로 앱이 사용자에게 더 반응할 수 있습니다. 사전 렌더링은 검색 엔진이 페이지 순위를 계산하는 데 사용하는 초기 HTTP 응답에 대한 콘텐츠를 렌더링하여 SEO(검색 엔진 최적화)를 향상시킬 수도 있습니다.
미리 렌더링된 상태 유지
미리 렌더링된 상태를 유지하지 않으면 미리 렌더링하는 동안 사용된 상태를 잃게 되며 앱이 완전히 로드되면 다시 만들어야 합니다. 비동기적으로 상태가 만들어지면 구성 요소가 다시 렌더링될 때 미리 렌더링된 UI가 대체되므로 UI가 깜박일 수 있습니다.
다음 PrerenderedCounter1
카운터 구성 요소를 고려합니다. 구성 요소는 수명 주기 메서드에서 OnInitialized
미리 렌더링하는 동안 초기 임의 카운터 값을 설정합니다. 클라이언트에 SignalR 대한 연결이 설정되면 구성 요소가 다시 라우팅되고 두 번째로 실행될 때 OnInitialized
초기 개수 값이 바뀝니다.
PrerenderedCounter1.razor
:
@page "/prerendered-counter-1"
@rendermode @(new InteractiveServerRenderMode(prerender: true))
@inject ILogger<PrerenderedCounter1> Logger
<PageTitle>Prerendered Counter 1</PageTitle>
<h1>Prerendered Counter 1</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount;
protected override void OnInitialized()
{
currentCount = Random.Shared.Next(100);
Logger.LogInformation("currentCount set to {Count}", currentCount);
}
private void IncrementCount() => currentCount++;
}
앱을 실행하고 구성 요소에서 로깅을 검사합니다. 예제 출력은 다음과 같습니다.
참고 항목
앱이 대화형(향상된) 라우팅을 채택하고 내부 탐색을 통해 페이지에 도달하면 사전 렌더링이 발생하지 않습니다. 따라서 다음 출력을 보려면 구성 요소에 PrerenderedCounter1
대한 전체 페이지 다시 로드를 수행해야 합니다.
info: BlazorSample.Components.Pages.PrerenderedCounter1[0]
currentCount set to 41
info: BlazorSample.Components.Pages.PrerenderedCounter1[0]
currentCount set to 92
첫 번째 로깅된 개수는 미리 렌더링하는 동안 발생합니다. 구성 요소를 다시 렌더링할 때 미리 렌더링한 후 개수가 다시 설정됩니다. 개수가 41에서 92로 업데이트되면 UI에도 깜박임이 있습니다.
미리 렌더링하는 Blazor 동안 카운터의 초기 값을 유지하려면 서비스를 사용하여 PersistentComponentState 미리 렌더링된 페이지에서 상태를 유지하도록 지원합니다(및 페이지 또는 MVC 앱의 페이지 또는 뷰에 포함된 구성 요소의 Razor 경우 구성 요소 상태 태그 도우미 유지).
미리 렌더링된 상태를 유지하려면 서비스를 사용하여 PersistentComponentState 유지할 상태를 결정합니다. PersistentComponentState.RegisterOnPersisting은 앱이 일시 중지되기 전에 구성 요소 상태를 유지하도록 콜백을 등록합니다. 앱이 다시 시작될 때 상태가 검색됩니다.
다음 예제에서는 일반적인 패턴을 보여 줍니다.
{TYPE}
자리 표시자는 유지할 데이터의 형식을 나타냅니다.{TOKEN}
자리 표시자는 상태 식별자 문자열입니다. 자리 표시자가 상태를 보유하는 변수의 이름인 경우{VARIABLE}
를 사용하는nameof({VARIABLE})
것이 좋습니다. 상태 식별자에 사용하면nameof()
따옴표 붙은 문자열을 사용하지 않습니다.
@implements IDisposable
@inject PersistentComponentState ApplicationState
...
@code {
private {TYPE} data;
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
persistingSubscription =
ApplicationState.RegisterOnPersisting(PersistData);
if (!ApplicationState.TryTakeFromJson<{TYPE}>(
"{TOKEN}", out var restored))
{
data = await ...;
}
else
{
data = restored!;
}
}
private Task PersistData()
{
ApplicationState.PersistAsJson("{TOKEN}", data);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
다음 카운터 구성 요소 예제는 미리 렌더링하는 동안 카운터 상태를 유지하며 구성 요소를 초기화하는 상태를 검색합니다.
PrerenderedCounter2.razor
:
@page "/prerendered-counter-2"
@implements IDisposable
@inject ILogger<PrerenderedCounter2> Logger
@inject PersistentComponentState ApplicationState
<PageTitle>Prerendered Counter 2</PageTitle>
<h1>Prerendered Counter 2</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount;
private PersistingComponentStateSubscription persistingSubscription;
protected override void OnInitialized()
{
persistingSubscription =
ApplicationState.RegisterOnPersisting(PersistCount);
if (!ApplicationState.TryTakeFromJson<int>(
nameof(currentCount), out var restoredCount))
{
currentCount = Random.Shared.Next(100);
Logger.LogInformation("currentCount set to {Count}", currentCount);
}
else
{
currentCount = restoredCount!;
Logger.LogInformation("currentCount restored to {Count}", currentCount);
}
}
private Task PersistCount()
{
ApplicationState.PersistAsJson(nameof(currentCount), currentCount);
return Task.CompletedTask;
}
void IDisposable.Dispose() => persistingSubscription.Dispose();
private void IncrementCount() => currentCount++;
}
구성 요소가 실행되면 currentCount
미리 렌더링하는 동안 한 번만 설정됩니다. 구성 요소를 다시 렌더링하면 값이 복원됩니다. 예제 출력은 다음과 같습니다.
참고 항목
앱이 대화형 라우팅을 채택하고 내부 탐색을 통해 페이지에 도달하면 사전 렌더링이 발생하지 않습니다. 따라서 다음 출력을 보려면 구성 요소에 PrerenderedCounter2
대한 전체 페이지 다시 로드를 수행해야 합니다.
info: BlazorSample.Components.Pages.PrerenderedCounter2[0]
currentCount set to 96
info: BlazorSample.Components.Pages.PrerenderedCounter2[0]
currentCount restored to 96
미리 렌더링하는 동안 사용된 것과 동일한 상태로 구성 요소를 초기화하면 비용이 많이 드는 초기화 단계가 한 번만 실행됩니다. 렌더링된 UI도 미리 렌더링된 UI와 일치하므로 브라우저에서 깜박임이 발생하지 않습니다.
지속형 미리 렌더링된 상태는 구성 요소 상태를 복원하는 데 사용되는 클라이언트로 전송됩니다. 클라이언트 쪽 렌더링(CSR InteractiveWebAssembly
) 중에 데이터는 브라우저에 노출되며 중요한 개인 정보를 포함해서는 안 됩니다. 대화형 서버 쪽 렌더링(대화형 SSR InteractiveServer
) 중에 ASP.NET Core Data Protection 은 데이터가 안전하게 전송되도록 합니다. 렌더링 모드는 InteractiveAuto
WebAssembly와 서버 대화형 작업을 결합하므로 CSR 사례와 같이 브라우저에 대한 데이터 노출을 고려해야 합니다.
페이지 및 뷰에 포함된 구성 요소(Razor Pages/MVC)
페이지 또는 MVC 앱의 페이지 또는 보기에 포함된 구성 요소의 경우 앱 레이아웃의 Razor 닫는 </body>
태그 내에 HTML 태그를 사용하여 <persist-component-state />
구성 요소 상태 태그 유지 도우미를 추가해야 합니다. Pages 및 MVC 앱에 Razor 만 필요합니다. 자세한 내용은 ASP.NET Core에서 구성 요소 상태 태그 도우미 유지를 참조 하세요.
Pages/Shared/_Layout.cshtml
:
<body>
...
<persist-component-state />
</body>
대화형 라우팅 및 미리 렌더링
대화형 라우팅에 대한 내부 탐색에는 서버에서 새 페이지 콘텐츠를 요청하는 작업이 포함되지 않습니다. 따라서 내부 페이지 요청에 대해 미리 렌더링이 발생하지 않습니다.
이 PersistentComponentState 서비스는 향상된 페이지 탐색 이벤트가 아닌 초기 페이지 로드에서 만 작동합니다. 앱이 영구 구성 요소 상태를 활용하는 페이지에 대한 전체(비확장) 탐색을 수행하는 경우 앱이 대화형이 될 때 사용할 수 있는 지속형 상태가 제공됩니다. 그러나 대화형 회로가 이미 설정되었고 지속형 구성 요소 상태를 렌더링하는 페이지로 향상된 탐색이 수행되는 경우 해당 상태는 기존 회로에서 사용할 수 없습니다. 서비스는 PersistentComponentState 향상된 탐색을 인식하지 못하며 이미 실행 중인 구성 요소에 상태 업데이트를 제공하는 메커니즘이 없습니다.
미리 렌더링 지침
미리 렌더링 지침은 주제별로 설명서에 Blazor 정리되어 있습니다. 다음 링크는 주체가 설정한 설명서 전체의 모든 미리 렌더링 지침을 다룹니다.
기본 사항
- OnNavigateAsync 은 미리 렌더링할 때 두 번 실행됩니다. 다음을 사용하여 비동기 탐색 이벤트 처리
OnNavigateAsync
- 시작: C# 코드의 컨트롤 헤더
- 오류 처리: 미리 렌더링
- SignalR: 미리 렌더링된 상태 크기 및 SignalR 메시지 크기 제한
- OnNavigateAsync 은 미리 렌더링할 때 두 번 실행됩니다. 다음을 사용하여 비동기 탐색 이벤트 처리
구성 요소
- 미리 렌더링하는 동안 콘텐츠 제어
<head>
- Razor 미리 렌더링과 관련된 구성 요소 수명 주기 주체
- 구성 요소 초기화(
OnInitialized{Async}
) - 구성 요소 렌더링 후(
OnAfterRender{Async}
) - 미리 렌더링한 후 상태 저장 다시 연결
- JavaScript interop 미리 렌더링: 이 섹션은 .NET에서 JavaScript를 호출하고 JavaScript에서 .NET을 호출하는 두 interop JS 문서에도 나타납니다.
- 구성 요소 초기화(
- QuickGrid 구성 요소 샘플 앱: 샘플 앱용 Blazor QuickGrid는 GitHub Pages에서 호스트됩니다. 사이트는 커뮤니티에서 유지 관리하는
BlazorWasmPrerendering.Build
GitHub 프로젝트를 사용하는 정적 미리 렌더링 덕분에 빠르게 로드됩니다. - 구성 요소를 Pages 및 MVC 앱에 Razor 통합할 때 미리 렌더링
- 미리 렌더링하는 동안 콘텐츠 제어
인증 및 권한 부여
상태 관리: 미리 렌더링 처리: 핸들 미리 렌더링 섹션 외에도 문서의 다른 여러 섹션에는 미리 렌더링에 대한 설명이 포함되어 있습니다.
ASP.NET Core