Share via


Bibliotecas de clases de Razor (RCL) para ASP.NET Core con representación estática en el lado servidor (SSR estática)

En este artículo se ofrece orientación a los creadores de bibliotecas de componentes que estén pensando en admitir la representación estática en el lado servidor (SSR estática).

Blazor fomenta el desarrollo de un ecosistema de bibliotecas de componentes comerciales y de código abierto, denominadas formalmente bibliotecas de clases de Razor (RCL). Los desarrolladores también pueden crear componentes reutilizables para compartir componentes de forma privada entre aplicaciones dentro de sus propias empresas. Idealmente, los componentes se desarrollan para su compatibilidad con tantos modelos de hospedaje y de representación como sea posible. La SSR estática presenta restricciones adicionales que pueden hacer más difícil la compatibilidad que los modos de representación interactivos.

Descripción de las funcionalidades y restricciones de la SSR estática

La SSR estática es un modo en el que los componentes se ejecutan cuando el servidor controla una solicitud HTTP entrante. Blazor representa el componente como HTML y se incluye en la respuesta. Una vez enviada la respuesta, se descarta el estado del representador y el componente del lado servidor, por lo que lo único que queda es HTML en el explorador.

La ventaja de este modo es que supone un hospedaje más barato y escalable, ya que no se requieren recursos de servidor en curso para contener el estado del componente, no se debe mantener ninguna conexión en curso entre el explorador y el servidor, y no se requiere ninguna carga de WebAssembly en el explorador.

De forma predeterminada, todos los componentes existentes se pueden usar con SSR estática. Sin embargo, la desventaja de este modo es que los controladores de eventos, como @onclick†, no se pueden ejecutar por los siguientes motivos:

  • No hay ningún código .NET en el explorador para ejecutarlos.
  • El servidor descarta inmediatamente todos los estados del componente y el representador que se necesitarían para ejecutar los controladores de eventos o para volver a representar las mismas instancias de componente.

†Hay una excepción especial para el controlador de eventos @onsubmit para formularios, el cual siempre es funcional, independientemente del modo de representación.

Esto equivale a cómo se comportan los componentes durante la representación previa, antes de que se inicie un circuito de Blazor o un entorno de ejecución de Blazor WebAssembly.

En el caso de los componentes cuya única función es generar contenido DOM de solo lectura, estos comportamientos de la SSR estática son completamente suficientes. Sin embargo, los creadores de bibliotecas deben tener en cuenta qué enfoque adoptar al incluir componentes interactivos en sus bibliotecas.

Opciones para creadores de componentes

Existen tres planteamientos principales:

  • No usar comportamientos interactivos (básico)

    En el caso de los componentes cuya única función es generar contenido DOM de solo lectura, no es necesario que el desarrollador realice ninguna acción especial. Estos componentes funcionan naturalmente con cualquier modo de representación.

    Ejemplos:

    • Componente de "tarjeta de usuario" que carga los datos correspondientes a una persona y los representa en una interfaz de usuario estilizada con una foto, un puesto de trabajo y otros detalles.
    • Un componente de "vídeo" que actúa como contenedor alrededor del elemento HTML <video>, lo que facilita su uso en un componente de Razor.
  • Requerir representación interactiva (básico)

    Puede optar por requerir que el componente solo se use con la representación interactiva. Esto limita la aplicabilidad del componente, pero significa que puede confiar libremente en controladores de eventos arbitrarios. Incluso en ese caso, debe evitar declarar un @rendermode específico y permitir que el creador de la aplicación que usa la biblioteca seleccione uno.

    Ejemplos:

    • Un componente de edición de vídeo en el que los usuarios pueden unir y volver a ordenar segmentos de vídeo. Incluso si hubiera una manera de representar estas operaciones de edición con botones HTML sin formato y publicaciones de formulario, la experiencia del usuario sería inaceptable sin verdadera interactividad.
    • Un editor de documentos colaborativos que debe mostrar las actividades de otros usuarios en tiempo real.
  • Uso de comportamientos interactivos, pero diseño para SSR estática y mejora progresiva (avanzado)

    Muchos comportamientos interactivos se pueden implementar solo con funcionalidades HTML. Con un buen conocimiento de HTML y CSS, a menudo puede generar una base de referencia útil de funcionalidad que use la SSR estática. Puede incluso declarar controladores de eventos que implementen comportamientos más avanzados y opcionales, que solo funcionan en modos de representación interactivos.

    Ejemplos:

    • Un componente de cuadrícula. En la SSR estática, el componente solo puede admitir la visualización de datos y la navegación entre páginas (implementada con vínculos <a>). Cuando se usa con la representación interactiva, el componente puede agregar ordenación y filtrado en directo.
    • Un componente de conjunto de pestañas. Siempre que la navegación entre pestañas se logre mediante vínculos <a> y el estado solo se mantenga en los parámetros de consulta de dirección URL, el componente puede funcionar sin @onclick.
    • Un componente de carga de archivos avanzado. En la SSR estática, el componente puede comportarse como un <input type=file> nativo. Cuando se usa con la representación interactiva, el componente también puede mostrar el progreso de la carga.
    • Un tablero de cotizaciones. En la SSR estática, el componente puede mostrar la cotización de las acciones en el momento en que se representa el HTML. Si se usa con la representación interactiva, el componente puede actualizar el precio de las acciones en tiempo real.

En cualquiera de estas estrategias existe también la opción de implementar características interactivas con JavaScript.

A la hora de elegir entre estos enfoques, los creadores de componentes reutilizables de Razor deben sopesar los costos y las ventajas. El componente es más útil y tiene una base de usuarios potenciales más amplia si admite todos los modos de representación, incluido la SSR estática. Sin embargo, se necesita más trabajo para diseñar e implementar un componente que admita y aproveche mejor cada modo de representación.

Cuándo usar la directiva @rendermode

En la mayoría de los casos, los creadores de componentes reutilizables no deben especificar un modo de representación, incluso cuando se requiera interactividad. Esto se debe a que el creador del componente no sabe si la aplicación permite la compatibilidad con InteractiveServer, InteractiveWebAssembly o de ambos con InteractiveAuto. Si no especifica un @rendermode, el autor del componente deja la elección al desarrollador de la aplicación.

Incluso si el creador del componente piensa que la interactividad es necesaria, puede haber casos en los que el creador de una aplicación considere que es suficiente usar SSR estática solo. Por ejemplo, puede parecer que un componente de mapa con interactividad de arrastre y zoom requiere interactividad. Sin embargo, es posible que en algunos casos solo sea necesario representar una imagen estática del mapa y evitar las funciones de arrastre y zoom.

La única razón por la que un creador de componentes reutilizables debería usar la directiva @rendermode en su componente es si la implementación está completamente asociada a un modo de representación específico y ciertamente se produciría un error si se usara en un modo diferente. Piense en un componente cuyo objetivo principal sea interactuar directamente con el sistema operativo host mediante API específicas de Windows o Linux. Puede que sea imposible usar este componente en WebAssembly. Si es así, es razonable declarar @rendermode InteractiveServer para el componente.

Representación de streaming

Los componentes reutilizables de Razor son libres de declarar @attribute [StreamRendering] para la representación de streaming (API de atributo [StreamRendering]). Esto da como resultado actualizaciones incrementales de la interfaz de usuario durante la SSR estática. Dado que los mismos patrones de carga de datos producen actualizaciones incrementales de la interfaz de usuario durante la representación interactiva, independientemente de la presencia del atributo [StreamRendering], el componente podrá comportarse correctamente en todos los casos. Incluso en los casos en los que se suprime la SSR estática de streaming en el servidor, el componente sigue representando su estado final correcto.

Los componentes reutilizables de Razor pueden usar vínculos y navegación mejorada. Las etiquetas HTML <a> deben producir comportamientos equivalentes con o sin un componente Router interactivo e independientemente de si la navegación mejorada está habilitada o deshabilitada en un nivel antecesor en el DOM.

Uso de formularios entre modos de representación

Los componentes reutilizables de Razor pueden incluir formularios (ya sea <form> o <EditForm>), ya que estos se pueden implementar para funcionar de forma equivalente en los modos de representación estáticos y en los interactivos.

Considere el ejemplo siguiente:

<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()
    {
        ...
    }
}

Las API Enhance, FormName y SupplyParameterFromFormAttribute solo se usan durante la SSR estática y se omiten durante la representación interactiva. El formulario funciona correctamente durante la representación interactiva y la SSR estática.

Evitar las API específicas de SSR estática

Para que un componente reutilizable funcione en todos los modos de representación, no confíe en HttpContext porque solo está disponible durante la SSR estática. No tiene sentido utilizar la API HttpContext durante la representación interactiva porque en esos momentos no hay ninguna solicitud HTTP activa en curso. No tiene sentido pensar en establecer un código de estado o escribir en la respuesta.

Los componentes reutilizables son libres de recibir un HttpContext cuando estén disponibles, de la siguiente manera:

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

El valor es null durante la representación interactiva y solo se establece durante la SSR estática.

En muchos casos, hay mejores alternativas que usar HttpContext. Si necesita conocer la dirección URL actual o realizar un redireccionamiento, las API en NavigationManager funcionan con todos los modos de representación. Si necesita conocer el estado de autenticación del usuario, es preferible usar el servicio AuthenticationStateProvider de Blazor antes que usar HttpContext.User.