정적 서버 쪽 렌더링(정적 SSR)이 있는 ASP.NET Core Razor 클래스 라이브러리(RCL)

이 문서에서는 정적 서버 쪽 렌더링(정적 SSR)에 대한 지원을 고려하는 구성 요소 라이브러리 작성자를 위한 지침을 제공합니다.

Blazor는 공식적으로 클래스 라이브러리(RCL)라고 하는 Razor 오픈 소스 및 상업용 구성 요소 라이브러리의 에코시스템 개발을 장려합니다. 개발자는 자체 회사 내의 앱에서 구성 요소를 비공개로 공유하기 위해 재사용 가능한 구성 요소를 만들 수도 있습니다. 구성 요소는 가능한 한 많은 호스팅 모델 및 렌더링 모드와 호환되도록 개발됩니다. 정적 SSR은 대화형 렌더링 모드보다 지원하기가 더 어려울 수 있는 추가 제한을 도입합니다.

정적 SSR의 기능 및 제한 사항 이해

정적 SSR은 서버가 들어오는 HTTP 요청을 처리할 때 구성 요소가 실행되는 모드입니다. Blazor 는 응답에 포함된 HTML로 구성 요소를 렌더링합니다. 응답이 전송되면 서버 쪽 구성 요소 및 렌더러 상태가 카드 해제되므로 다시 기본 모두 브라우저의 HTML입니다.

이 모드의 이점은 구성 요소 상태를 유지하는 데 지속적인 서버 리소스가 필요하지 않고, 브라우저와 서버 간에 지속적인 연결을 기본 안 되며, 브라우저에 WebAssembly 페이로드가 필요하지 않으므로 더 저렴하고 확장성 있는 호스팅입니다.

기본적으로 모든 기존 구성 요소는 여전히 정적 SSR과 함께 사용할 수 있습니다. 그러나 이 모드의 비용은 다음과 같은 @onclick이유로 † 같은 이벤트 처리기를 실행할 수 없다는 것입니다.

  • 브라우저에는 실행할 .NET 코드가 없습니다.
  • 서버는 이벤트 처리기를 실행하거나 동일한 구성 요소 인스턴스를 다시 렌더링하는 데 필요한 구성 요소 및 렌더러 상태를 즉시 카드.

† 렌더링 모드에 관계없이 항상 작동하는 폼의 이벤트 처리기에 대한 @onsubmit 특별한 예외입니다.

이는 회로 또는 Blazor WebAssembly 런타임이 시작되기 전에 Blazor 미리 렌더링하는 동안 구성 요소가 동작하는 방식과 동일합니다.

읽기 전용 DOM 콘텐츠를 생성하는 역할만 있는 구성 요소의 경우 정적 SSR에 대한 이러한 동작은 완전히 충분합니다. 그러나 라이브러리 작성자는 라이브러리에 대화형 구성 요소를 포함할 때 취할 방법을 고려해야 합니다.

구성 요소 작성자용 옵션

세 가지 주요 접근 방식이 있습니다.

  • 대화형 동작 사용 안 함 (기본)

    읽기 전용 DOM 콘텐츠를 생성하는 역할만 있는 구성 요소의 경우 개발자는 특별한 조치를 취할 필요가 없습니다. 이러한 구성 요소는 자연스럽게 모든 렌더링 모드에서 작동합니다.

    예:

    • 개인에 해당하는 데이터를 로드하고 사진, 직위 및 기타 세부 정보를 사용하여 스타일이 지정된 UI에 렌더링하는 "사용자 카드" 구성 요소입니다.
    • HTML <video> 요소 주위의 래퍼 역할을 하는 "비디오" 구성 요소로 구성 요소에서 Razor 더 편리하게 사용할 수 있습니다.
  • 대화형 렌더링 필요(기본)

    구성 요소가 대화형 렌더링에만 사용하도록 요구할 수 있습니다. 이렇게 하면 구성 요소의 적용 가능성이 제한되지만 임의 이벤트 처리기를 자유롭게 사용할 수 있습니다. 그럼에도 불구하고 특정 @rendermode 항목을 선언하지 않고 라이브러리를 사용하는 앱 작성자가 하나를 선택하도록 허용해야 합니다.

    예:

    • 사용자가 비디오 세그먼트를 스플라이스하고 순서를 다시 정렬할 수 있는 비디오 편집 구성 요소입니다. 일반 HTML 단추 및 양식 게시물을 사용하여 이러한 편집 작업을 나타내는 방법이 있더라도 사용자 환경은 실제 대화형 작업 없이는 허용되지 않습니다.
    • 다른 사용자의 활동을 실시간으로 표시해야 하는 공동 작업 문서 편집기입니다.
  • 대화형 동작을 사용하지만 정적 SSR 및 점진적 향상 을 위해 디자인(고급)

    HTML 기능만 사용하여 많은 대화형 동작을 구현할 수 있습니다. HTML 및 CSS를 잘 이해하면 종종 정적 SSR에서 작동하는 유용한 기능 기준을 생성할 수 있습니다. 대화형 렌더링 모드에서만 작동하는 고급 선택적 동작을 구현하는 이벤트 처리기를 선언할 수 있습니다.

    예:

    • 그리드 구성 요소입니다. 정적 SSR에서 구성 요소는 데이터 표시 및 페이지 간 탐색(링크로 <a> 구현)만 지원할 수 있습니다. 대화형 렌더링과 함께 사용할 경우 구성 요소는 라이브 정렬 및 필터링을 추가할 수 있습니다.
    • 탭 세트 구성 요소입니다. 링크를 사용하여 <a> 탭 간 탐색을 수행하고 상태가 URL 쿼리 매개 변수에서만 유지되는 한 구성 요소는 없이 @onclick작동할 수 있습니다.
    • 고급 파일 업로드 구성 요소입니다. 정적 SSR에서 구성 요소는 네이티브 <input type=file>로 동작할 수 있습니다. 대화형 렌더링과 함께 사용할 경우 구성 요소에 업로드 진행률도 표시할 수 있습니다.
    • 주식 시세입니다. 정적 SSR에서 구성 요소는 HTML이 렌더링될 때 주식 견적을 표시할 수 있습니다. 대화형 렌더링과 함께 사용할 경우 구성 요소는 실시간으로 주가를 업데이트할 수 있습니다.

이러한 전략의 경우 JavaScript를 사용하여 대화형 기능을 구현하는 옵션도 있습니다.

이러한 방법 중에서 선택하려면 재사용 가능한 Razor 구성 요소 작성자가 비용/혜택을 절충해야 합니다. 구성 요소가 더 유용하며 정적 SSR을 비롯한 모든 렌더링 모드를 지원하는 경우 더 광범위한 잠재적 사용자 기반이 있습니다. 그러나 각 렌더링 모드를 지원하고 가장 잘 활용하는 구성 요소를 디자인하고 구현하려면 더 많은 작업이 필요합니다.

지시문을 사용하는 경우 @rendermode

대부분의 경우 다시 사용할 수 있는 구성 요소 작성자는 대화형 작업이 필요한 경우에도 렌더링 모드를 지정해서는됩니다. 이는 구성 요소 작성자가 앱에서 지원을 InteractiveServerInteractiveWebAssembly사용할 수 있는지 또는 둘 다 InteractiveAuto사용할 수 있는지 여부를 모르기 때문입니다. 구성 요소 작성자는 @rendermode지정하지 않음으로써 앱 개발자에게 선택을 둡니다.

구성 요소 작성자가 대화형 작업이 필요하다고 생각하더라도 앱 작성자가 정적 SSR만 사용하기에 충분하다고 생각하는 경우도 있을 수 있습니다. 예를 들어 끌기 및 확대/축소 대화형 작업을 사용하는 맵 구성 요소에는 대화형 작업이 필요할 수 있습니다. 그러나 일부 시나리오에서는 정적 맵 이미지를 렌더링하고 끌기/확대/축소 기능을 피해야 할 수 있습니다.

재사용 가능한 구성 요소 작성자가 해당 구성 요소에서 지시문을 사용해야 @rendermode 하는 유일한 이유는 구현이 기본적으로 하나의 특정 렌더링 모드에 결합되어 다른 모드에서 사용되는 경우 오류가 발생할 수 있기 때문입니다. Windows 또는 Linux 관련 API를 사용하여 호스트 OS와 직접 상호 작용하는 핵심 목적의 구성 요소를 고려합니다. WebAssembly에서 이러한 구성 요소를 사용하는 것은 불가능할 수 있습니다. 그렇다면 구성 요소에 대해 선언 @rendermode InteractiveServer 하는 것이 합리적입니다.

스트리밍 렌더링

재사용 가능한 구성 요소는 스트리밍 렌더링([StreamRendering]특성 API)에 대해 자유롭게 선언 @attribute [StreamRendering] 할 수 Razor 있습니다. 이로 인해 정적 SSR 중에 증분 UI 업데이트가 발생합니다. 동일한 데이터 로드 패턴은 특성의 [StreamRendering] 존재와 관계없이 대화형 렌더링 중에 증분 UI 업데이트를 생성하므로 모든 경우에 구성 요소가 올바르게 작동할 수 있습니다. 서버에서 스트리밍 정적 SSR이 표시되지 않는 경우에도 구성 요소는 여전히 올바른 최종 상태를 렌더링합니다.

재사용 가능한 Razor 구성 요소는 링크 및 향상된 탐색을 사용할 수 있습니다. HTML <a> 태그는 대화형 Router 구성 요소의 사용 여부에 관계없이 동등한 동작을 생성해야 하며, DOM의 상위 수준에서 향상된 탐색을 사용할 수 있는지 여부와 사용하지 않도록 설정해야 합니다.

렌더링 모드에서 양식 사용

다시 사용할 수 있는 Razor 구성 요소에는 폼(또는 <form><EditForm>)이 포함될 수 있습니다. 정적 및 대화형 렌더링 모드 모두에서 동등하게 작동하도록 구현할 수 있기 때문일 수 있습니다.

다음 예제를 참조하세요.

<EditForm Enhance FormName="NewProduct" Model="Model" OnValidSubmit="SaveProduct">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <p>Name: <InputText @bind-Value="Item.Name" /></p>

    <button type="submit">Submit</button>
</EditForm>

@code {
    [SupplyParameterFromForm]
    public Product? Model { get; set; }

    protected override void OnInitialized() => Model ??= new();

    private async Task Save()
    {
        ...
    }
}

FormNameSupplyParameterFromFormAttribute API는 Enhance정적 SSR 중에만 사용되며 대화형 렌더링 중에 무시됩니다. 양식은 대화형 및 정적 SSR 모두에서 올바르게 작동합니다.

정적 SSR과 관련된 API 방지

모든 렌더링 모드에서 작동하는 재사용 가능한 구성 요소를 만들려면 정적 SSR 중에만 사용할 수 있으므로 사용하지 마세요 HttpContext . HttpContext 해당 시간에 활성 HTTP 요청이 없기 때문에 API는 대화형 렌더링 중에 사용하는 것이 적합하지 않습니다. 상태 코드를 설정하거나 응답에 쓰는 것은 의미가 없습니다.

재사용 가능한 구성 요소는 다음과 같이 사용 가능한 경우 무료로 받을 HttpContext 수 있습니다.

[CascadingParameter]
public HttpContext? Context { get; set; }

값은 null 대화형 렌더링 중이며 정적 SSR 중에만 설정됩니다.

대부분의 경우 .를 사용하는 HttpContext것보다 더 나은 대안이 있습니다. 현재 URL을 알고 있거나 리디렉션을 수행해야 하는 경우 API는 모든 렌더링 모드에서 NavigationManager 작동합니다. 사용자의 인증 상태를 알아야 하는 경우 사용 하 여 's AuthenticationStateProvider 서비스를 사용 Blazor합니다HttpContext.User.