ASP.NET библиотеки классов Core Razor (RCLs) со статической отрисовкой на стороне сервера (статический SSR)

В этой статье приводятся рекомендации для авторов библиотек компонентов, которые рассматривают поддержку статической отрисовки на стороне сервера (статический SSR).

Blazorпоощряет разработку экосистемы библиотек с открытым исходным кодом и коммерческих компонентов, формально называемых Razor библиотеками классов (RCLS). Разработчики также могут создавать повторно используемые компоненты для совместного использования компонентов в частных приложениях в своих собственных компаниях. В идеале компоненты разрабатываются для обеспечения совместимости с максимально большим количеством моделей размещения и режимов отрисовки. Статический SSR вводит дополнительные ограничения, которые могут быть более сложными для поддержки, чем интерактивные режимы отрисовки.

Общие сведения о возможностях и ограничениях статического SSR

Статический SSR — это режим, в котором компоненты выполняются при обработке входящего HTTP-запроса. Blazor отрисовывает компонент в виде HTML, который включен в ответ. После отправки ответа серверный компонент и состояние отрисовщика отменяется карта поэтому все, что остается HTML в браузере.

Преимущество этого режима является более дешевым, более масштабируемым размещением, так как текущие ресурсы сервера не требуются для хранения состояния компонента, не должно поддерживаться текущее подключение между браузером и сервером, а полезные данные WebAssembly не требуются в браузере.

По умолчанию все существующие компоненты по-прежнему можно использовать со статическим SSR. Однако стоимость этого режима заключается в том, что обработчики событий, такие как @onclick†, не могут выполняться по следующим причинам:

  • В браузере нет кода .NET для их запуска.
  • Сервер немедленно отключил карта любой компонент и состояние отрисовщика, которое потребуется для выполнения обработчиков событий или для rerender одних и тех же экземпляров компонентов.

† Специальное исключение обработчика @onsubmit событий для форм, которое всегда работает независимо от режима отрисовки.

Это эквивалентно работе компонентов во время предварительной подготовки перед запуском Blazor канала или Blazor WebAssembly среды выполнения.

Для компонентов, единственная роль которых состоит в том, чтобы создавать содержимое DOM только для чтения, эти поведение для статического SSR полностью достаточно. Однако авторы библиотеки должны учитывать, какой подход следует использовать при включении интерактивных компонентов в их библиотеках.

Параметры для авторов компонентов

Существует три основных подхода:

  • Не используйте интерактивное поведение (базовый)

    Для компонентов, единственная роль которых состоит в том, чтобы создать содержимое только для чтения DOM, разработчику не требуется выполнять какие-либо специальные действия. Эти компоненты естественно работают с любым режимом отрисовки.

    Примеры:

    • Компонент "пользователь карта", который загружает данные, соответствующие человеку, и отображает его в стилизованном пользовательском интерфейсе с фотографией, названием задания и другими сведениями.
    • Компонент "видео", который выступает в качестве оболочки вокруг HTML-элемента <video> , что делает его более удобным для использования в компоненте Razor .
  • Требовать интерактивную отрисовку (базовый)

    Вы можете выбрать, чтобы компонент использовался только с интерактивной отрисовкой. Это ограничивает применимость компонента, но означает, что вы можете свободно полагаться на произвольные обработчики событий. Даже тогда следует избежать объявления определенного @rendermode и разрешить автору приложения, который использует библиотеку для выбора.

    Примеры:

    • Компонент редактирования видео, в котором пользователи могут сплясти и повторно упорядочить сегменты видео. Даже если существует способ представления этих операций редактирования с помощью простых кнопок HTML и записей формы, взаимодействие с пользователем будет неприемлемым без истинной интерактивности.
    • Редактор документов для совместной работы, который должен отображать действия других пользователей в режиме реального времени.
  • Использование интерактивных действий, но проектирование статического SSR и прогрессивного улучшения (advanced)

    Многие интерактивные действия можно реализовать с помощью только возможностей HTML. С хорошим пониманием HTML и CSS часто можно создать полезные базовые показатели функциональности, которая работает со статическим SSR. Вы по-прежнему можете объявить обработчики событий, реализующие более сложные, необязательные действия, которые работают только в интерактивных режимах отрисовки.

    Примеры:

    • Компонент сетки. В рамках статического SSR компонент может поддерживать только отображение данных и переход между страницами (реализовано со <a> ссылками). При использовании с интерактивной отрисовкой компонент может добавить динамическое сортировку и фильтрацию.
    • Компонент набора вкладок. Если навигация между вкладками достигается с помощью <a> ссылок и состояния, удерживается только в параметрах URL-запроса, компонент может работать без @onclick.
    • Дополнительный компонент отправки файлов. В рамках статического SSR компонент может вести себя как собственный <input type=file>. При использовании с интерактивной отрисовкой компонент также может отображать ход отправки.
    • Тикер акций. В рамках статического SSR компонент может отображать акции на момент отрисовки HTML. При использовании с интерактивной отрисовкой компонент может обновить цену акций в режиме реального времени.

Для любой из этих стратегий также можно реализовать интерактивные функции с помощью JavaScript.

Чтобы выбрать один из этих подходов, авторы повторно используемых Razor компонентов должны сделать компромисс по затратам и преимуществам. Компонент более полезен и имеет более широкую пользовательскую базу, если она поддерживает все режимы отрисовки, включая статический SSR. Однако для разработки и реализации компонента, поддерживающего и эффективного использования каждого режима отрисовки, требуется больше работы.

Когда следует использовать директиву @rendermode

В большинстве случаев авторы повторно используемых компонентов не должны указывать режим отрисовки, даже если требуется интерактивность. Это связано с тем, что автор компонента не знает, включает ли приложение поддержку InteractiveServer, InteractiveWebAssemblyили оба с InteractiveAuto. Не указывая, @rendermodeавтор компонента оставляет выбор разработчику приложения.

Даже если автор компонента считает, что требуется интерактивность, могут по-прежнему возникать случаи, когда автор приложения считает достаточно использовать статический SSR. Например, компонент карты с интерактивностью перетаскивания и масштабирования может потребовать интерактивности. Однако некоторые сценарии могут вызываться только для отрисовки статического изображения карты и предотвращения перетаскивания и масштабирования функций.

Единственная причина, по которой автор повторно используемых компонентов должен использовать @rendermode директиву для своего компонента, заключается в том, что реализация имеет основную связь с одним конкретным режимом отрисовки и, безусловно, приведет к ошибке, если она используется в другом режиме. Рассмотрим компонент с основной целью взаимодействия непосредственно с ос узла с помощью API windows или Linux. Возможно, невозможно использовать такой компонент в WebAssembly. В этом случае разумно объявить @rendermode InteractiveServer для компонента.

Потоковая отрисовка

Повторно используемые Razor компоненты могут объявляться @attribute [StreamRendering] для потоковой отрисовки ([StreamRendering] API атрибутов). Это приводит к добавочным обновлениям пользовательского интерфейса во время статического SSR. Так как одни и те же шаблоны загрузки данных создают добавочные обновления пользовательского интерфейса во время интерактивной отрисовки независимо от наличия атрибута [StreamRendering] , компонент может вести себя правильно во всех случаях. Даже в тех случаях, когда потоковый статический SSR подавляется на сервере, компонент по-прежнему отображает правильное окончательное состояние.

Повторно используемые Razor компоненты могут использовать ссылки и расширенную навигацию. Теги HTML <a> должны создавать эквивалентные действия с интерактивным Router компонентом или без нее, и независимо от того, включена или отключена расширенная навигация на уровне предков в DOM.

Использование форм в режимах отрисовки

Повторно используемые Razor компоненты могут включать формы (или<EditForm>) так как они могут быть реализованы в эквивалентной работе как в статических, так <form> и в интерактивных режимах отрисовки.

Рассмотрим следующий пример:

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

FormNameИнтерфейсы EnhanceAPI используются SupplyParameterFromFormAttribute только во время статического SSR и игнорируются во время интерактивной отрисовки. Форма работает правильно во время интерактивного и статического SSR.

Избегайте интерфейсов API, относящихся к статическим SSR

Чтобы сделать повторно используемый компонент, который работает во всех режимах отрисовки, не полагается HttpContext на то, что он доступен только во время статического SSR. HttpContext API не имеет смысла использовать во время интерактивной отрисовки, так как в это время нет активного HTTP-запроса. Это бессмысленно думать о настройке кода состояния или записи в ответ.

Повторно используемые компоненты могут получать HttpContext доступные компоненты, как показано ниже.

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

Значение выполняется null во время интерактивной отрисовки и устанавливается только во время статического SSR.

Во многих случаях есть лучшие варианты, чем использование HttpContext. Если вам нужно знать текущий URL-адрес или выполнить перенаправление, API-интерфейсы работают NavigationManager со всеми режимами отрисовки. Если вам нужно знать состояние проверки подлинности пользователя, используйте BlazorAuthenticationStateProvider службу по сравнению с использованиемHttpContext.User.