Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão do .NET 9 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para a versão atual, consulte a versão do .NET 9 deste artigo.
Este artigo explica os cenários de pré-renderização dos componentes Razor para os componentes renderizados pelo servidor nos Blazor Web Apps.
A pré-geração é o processo de renderizar inicialmente o conteúdo da página no servidor sem habilitar manipuladores de eventos para controles renderizados. O servidor gera a interface do usuário HTML da página o mais rápido possível em resposta à solicitação inicial, o que dá a sensação de que o aplicativo é mais responsivo aos usuários. A pre-renderização também pode melhorar SEO (Otimização do Mecanismo de Pesquisa) ao gerar o conteúdo da resposta HTTP inicial que os mecanismos de pesquisa usam para calcular a classificação da página.
Persistência do estado pré-renderizado
Sem a persistência do estado pré-renderizado, há perda do estado usado durante a pré-renderização e ele deve ser recriado quando o aplicativo for totalmente carregado. Se qualquer estado for criado de maneira assíncrona, a interface do usuário poderá piscar à medida que a interface do usuário pré-renderizada for substituída quando o componente for renderizado novamente.
Considere o componente de contador PrerenderedCounter1
a seguir. O componente define um valor inicial de contador aleatório durante a pré-renderização no método do ciclo de vida OnInitialized
é executado uma segunda vez.
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++;
}
Execute o aplicativo e inspecione o log no componente. A seguir está a saída de exemplo:
Observação
Se o aplicativo adotar o roteamento interativo e a página for acessada por meio de uma navegação aprimorada interna, a pré-geração não ocorrerá. Portanto, você deve executar um recarregamento completo da página para que o componente PrerenderedCounter1
veja a saída a seguir. Para mais informações, consulte a seção Roteamento interativo e pré-renderização.
info: BlazorSample.Components.Pages.PrerenderedCounter1[0]
currentCount set to 41
info: BlazorSample.Components.Pages.PrerenderedCounter1[0]
currentCount set to 92
A primeira contagem registrada ocorre durante a pré-renderização. A contagem é definida novamente após a pré-renderização quando o componente é renderizado novamente. Há também uma cintilação na interface do usuário quando a contagem é atualizada de 41 para 92.
Para manter o valor inicial do contador durante a pré-geração, Blazor dá suporte ao estado persistente em uma página pré-gerada usando o PersistentComponentState serviço (e para componentes inseridos em páginas ou exibições de Razor páginas ou aplicativos MVC, o Auxiliar de Marca de Estado do Componente Persistente).
Para preservar o estado pré-renderizado, use o atributo [SupplyParameterFromPersistentComponentState]
para manter o estado nas propriedades. As propriedades com esse atributo são mantidas automaticamente usando o PersistentComponentState serviço durante a pré-geração. O estado é recuperado quando o componente é renderizado interativamente ou o serviço é instanciado.
Por padrão, as propriedades são serializadas usando o System.Text.Json serializador com configurações padrão. A serialização não é segura para operações de corte e requer a preservação dos tipos usados. Para obter mais informações, consulte Configurar o Trimmer para ASP.NET Core Blazor.
O seguinte componente de contador persiste o estado do contador durante a pré-renderização e recupera o estado para inicializar o componente.
- O
[SupplyParameterFromPersistentComponentState]
atributo é aplicado aoCounterState
tipo (State
). - O estado do contador é atribuído quando
null
emOnInitialized
e restaurado automaticamente quando o componente é renderizado de forma interativa.
PrerenderedCounter2.razor
:
@page "/prerendered-counter-2"
@inject ILogger<PrerenderedCounter2> Logger
<PageTitle>Prerendered Counter 2</PageTitle>
<h1>Prerendered Counter 2</h1>
<p role="status">Current count: @State?.CurrentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
[SupplyParameterFromPersistentComponentState]
public CounterState? State { get; set; }
protected override void OnInitialized()
{
if (State is null)
{
State = new() { CurrentCount = Random.Shared.Next(100) };
Logger.LogInformation("CurrentCount set to {Count}",
State.CurrentCount);
}
else
{
Logger.LogInformation("CurrentCount restored to {Count}",
State.CurrentCount);
}
}
private void IncrementCount()
{
if (State is not null)
{
State.CurrentCount++;
}
}
public class CounterState
{
public int CurrentCount { get; set; }
}
}
Quando o componente é executado, a CurrentCount
é definida apenas uma vez durante a pré-renderização. O valor é restaurado quando o componente é renderizado novamente. A seguir está a saída de exemplo:
Observação
Se o aplicativo adotar o roteamento interativo e a página for acessada por meio de uma navegação aprimorada interna, a pré-geração não ocorrerá. Portanto, você deve executar um recarregamento de página inteira para que o componente exiba a saída a seguir. Para mais informações, consulte a seção Roteamento interativo e pré-renderização.
info: BlazorSample.Components.Pages.PrerenderedCounter2[0]
CurrentCount set to 96
info: BlazorSample.Components.Pages.PrerenderedCounter2[0]
CurrentCount restored to 96
No exemplo a seguir, que serializa o estado para vários componentes do mesmo tipo:
- As propriedades anotadas com o
[SupplyParameterFromPersistentComponentState]
atributo são serializadas e desserializadas durante a pré-geração. - O
@key
atributo de diretiva é usado para garantir que o estado esteja corretamente associado à instância do componente. - A
Element
propriedade é inicializada no método doOnInitialized
ciclo de vida para evitar exceções de referências nulas, da mesma forma como as referências nulas são evitadas para parâmetros de consulta e dados de formulário.
PersistentChild.razor
:
<div>
<p>Current count: @Element.CurrentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</div>
@code {
[SupplyParameterFromPersistentComponentState]
public State Element { get; set; }
protected override void OnInitialized()
{
Element ??= new State();
}
private void IncrementCount()
{
Element.CurrentCount++;
}
private class State
{
public int CurrentCount { get; set; }
}
}
Parent.razor
:
@page "/parent"
@foreach (var element in elements)
{
<PersistentChild @key="element.Name" />
}
No exemplo que se segue, que serializa o estado de um serviço de injeção de dependência:
- As propriedades anotadas com o
[SupplyParameterFromPersistentComponentState]
atributo são serializadas durante a pré-geração e desserializadas quando o aplicativo se torna interativo. - O
AddPersistentService
método é usado para registrar o serviço para persistência. O modo de renderização é necessário porque o modo de renderização não pode ser inferido do tipo de serviço. Use qualquer um dos seguintes valores:-
RenderMode.Server
: o serviço está disponível para o modo de renderização do Servidor Interativo. -
RenderMode.Webassembly
: O serviço está disponível para o modo de renderização Interativo Webassembly. -
RenderMode.InteractiveAuto
: O serviço estará disponível para os modos de renderização do Servidor Interativo e WebAssembly Interativo se um componente for renderizado em qualquer um desses modos.
-
- O serviço é resolvido durante a inicialização de um modo de renderização interativo e as propriedades anotadas com o
[SupplyParameterFromPersistentComponentState]
atributo são desserializadas.
Observação
Apenas a persistência de serviços com escopo definido é suportada.
CounterService.cs
:
public class CounterService
{
[SupplyParameterFromPersistentComponentState]
public int CurrentCount { get; set; }
public void IncrementCount()
{
CurrentCount++;
}
}
Em Program.cs
:
builder.Services.AddPersistentService<CounterService>(RenderMode.InteractiveAuto);
As propriedades serializadas são identificadas pela instância real do serviço.
- Essa abordagem permite marcar uma abstração como um serviço persistente.
- Permite que as implementações reais sejam de tipos internos ou diferentes.
- Dá suporte a código compartilhado em assemblies diferentes.
- Os resultados em cada instância revelam as mesmas propriedades.
Como alternativa ao uso do modelo declarativo para persistir o estado usando o atributo [SupplyParameterFromPersistentComponentState]
, você pode usar o serviço PersistentComponentState diretamente, o que oferece maior flexibilidade para cenários complexos de persistência de estado. Chame PersistentComponentState.RegisterOnPersisting para registrar um callback para persistir o estado do componente durante a prerenderização. O estado é recuperado quando o componente é renderizado interativamente. Faça a chamada ao final do código de inicialização para evitar uma possível condição de corrida durante o desligamento do aplicativo.
O exemplo de componente de contador a seguir persiste o estado do contador durante a pré-renderização e recupera o estado para inicializar o componente.
PrerenderedCounter3.razor
:
@page "/prerendered-counter-3"
@implements IDisposable
@inject ILogger<PrerenderedCounter3> Logger
@inject PersistentComponentState ApplicationState
<PageTitle>Prerendered Counter 3</PageTitle>
<h1>Prerendered Counter 3</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()
{
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);
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistCount);
}
private Task PersistCount()
{
ApplicationState.PersistAsJson(nameof(currentCount), currentCount);
return Task.CompletedTask;
}
private void IncrementCount() => currentCount++;
void IDisposable.Dispose() => persistingSubscription.Dispose();
}
Quando o componente é executado, a currentCount
é definida apenas uma vez durante a pré-renderização. O valor é restaurado quando o componente é renderizado novamente. A seguir está a saída de exemplo:
Observação
Se o aplicativo adotar o roteamento interativo e a página for acessada por meio de uma navegação aprimorada interna, a pré-geração não ocorrerá. Portanto, você deve executar um recarregamento de página inteira para que o componente exiba a saída a seguir. Para mais informações, consulte a seção Roteamento interativo e pré-renderização.
info: BlazorSample.Components.Pages.PrerenderedCounter3[0]
currentCount set to 96
info: BlazorSample.Components.Pages.PrerenderedCounter3[0]
currentCount restored to 96
Para preservar o estado pré-renderizado, decida qual estado será persistido por meio do serviço PersistentComponentState. PersistentComponentState.RegisterOnPersisting registra um retorno de chamada para persistir o estado do componente durante a pré-renderização. O estado é recuperado quando o componente é renderizado interativamente. Faça a chamada ao final do código de inicialização para evitar uma possível condição de corrida durante o desligamento do aplicativo.
O exemplo de componente de contador a seguir persiste o estado do contador durante a pré-renderização e recupera o estado para inicializar o componente.
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()
{
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);
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistCount);
}
private Task PersistCount()
{
ApplicationState.PersistAsJson(nameof(currentCount), currentCount);
return Task.CompletedTask;
}
void IDisposable.Dispose() => persistingSubscription.Dispose();
private void IncrementCount() => currentCount++;
}
Quando o componente é executado, a currentCount
é definida apenas uma vez durante a pré-renderização. O valor é restaurado quando o componente é renderizado novamente. A seguir está a saída de exemplo:
Observação
Se o aplicativo adotar o roteamento interativo e a página for acessada por meio de uma navegação aprimorada interna, a pré-geração não ocorrerá. Portanto, você deve executar um recarregamento de página inteira para que o componente exiba a saída a seguir. Para mais informações, consulte a seção Roteamento interativo e pré-renderização.
info: BlazorSample.Components.Pages.PrerenderedCounter2[0]
currentCount set to 96
info: BlazorSample.Components.Pages.PrerenderedCounter2[0]
currentCount restored to 96
Ao inicializar componentes com o mesmo estado usado durante a pré-renderização, todas as etapas de inicialização dispendiosa só são executadas uma vez. A interface do usuário renderizada também corresponde à interface do usuário pré-renderizada, portanto, nenhuma cintilação ocorre no navegador.
O estado pré-renderizado persistente é transferido para o cliente, onde é usado para restaurar o estado do componente. Durante a renderização do lado do cliente (CSR, InteractiveWebAssembly
), os dados são expostos ao navegador e não devem conter informações confidenciais e privadas. Durante a renderização interativa do lado do servidor (SSR InteractiveServer
interativa), ASP.NET Core Data Protection garante que os dados sejam transferidos com segurança. O InteractiveAuto
modo de renderização combina WebAssembly e interatividade do servidor, por isso é necessário considerar a exposição de dados ao navegador, como no caso de CSR.
Componentes inseridos em páginas e exibições (Páginas/MVC Razor)
Para componentes inseridos em uma página ou exibição de um Razor aplicativo Pages ou MVC, você deve adicionar o Auxiliar de Marca de Estado do Componente Persist com a <persist-component-state />
marca HTML dentro da marca de fechamento </body>
do layout do aplicativo. Isso só é necessário em aplicativos MVC e Razor Pages. Para obter mais informações, consulte Persist Component State Tag Helper in ASP.NET Core.
Pages/Shared/_Layout.cshtml
:
<body>
...
<persist-component-state />
</body>
Roteamento interativo e pré-renderização
Quando o componente Routes
não define um modo de renderização, o aplicativo está usando interatividade e navegação por página/componente. Usando a navegação por página ou componente, a navegação interna é gerenciada pelo roteamento aprimorado assim que o aplicativo se torna interativo. †Internal nesse contexto significa que o destino da URL do evento de navegação é um Blazor endpoint dentro do aplicativo.
O serviço PersistentComponentState funciona apenas na carga inicial da página e não em eventos de navegação de página avançados internos.
Se o aplicativo executar uma navegação completa (não aprimorada) para uma página que utiliza estado do componente persistente, o estado persistido fica disponível para o aplicativo usar quando ele se tornar interativo.
Se um circuito interativo já tiver sido estabelecido e uma navegação aprimorada for executada em uma página utilizando o estado do componente persistente, o estado não será disponibilizado no circuito existente para uso do componente. Não é feita nenhuma pré-renderização para a solicitação de página interna, e o serviço PersistentComponentState não está ciente de que uma navegação aprimorada tenha ocorrido. Não há mecanismo para fornecer atualizações de estado para componentes que já estão em execução em um circuito existente. O motivo disso é que Blazor só dá suporte à passagem de estado do servidor para o cliente no momento em que o runtime é inicializado, não após o runtime ter sido iniciado.
O trabalho adicional na estrutura de Blazor para resolver esse cenário está em consideração para o .NET 10 (novembro de 2025). Para obter mais informações e discussão da comunidade sobre soluções alternativas sem suporte‡, consulte Suporte ao estado de componente persistente em navegações de página aprimoradas (dotnet/aspnetcore
nº 51584). ‡Soluções alternativas sem suporte não são sancionadas pela Microsoft para uso em aplicativos Blazor.
Use pacotes, abordagens e código de terceiros por sua conta e risco.
A Desativação da navegação aprimorada, que reduz o desempenho, mas também evita o problema de carregar o estado com PersistentComponentState para solicitações internas de página, é abordada em ASP.NET Core Roteamento e NavegaçãoBlazor.
Diretrizes de pré-renderização
As diretrizes de pré-renderização são organizadas na documentação do Blazor por assunto. Os seguintes links abrangem todas as diretrizes de pré-renderização em toda a documentação definidas por assunto:
Conceitos básicos
Componentes
-
Controlar
<head>
o conteúdo durante a pré-renderização - Modos de renderização
-
Razorobjetos do ciclo de vida do componente que são pertencentes à pré-renderização
-
Inicialização do componente (
OnInitialized{Async}
) -
Após a renderização do componente (
OnAfterRender{Async}
) - Reconexão com estado após a pré-renderização
- Pré-geração com interoperabilidade JavaScript: Esta seção também aparece nos dois JS artigos de interoperabilidade sobre chamar JavaScript do .NET e chamar o .NET do JavaScript.
- Lidar com ações assíncronas incompletas na renderização: diretrizes para renderização atrasada devido a tarefas de ciclo de vida de longa execução durante a pré-geração no servidor.
-
Inicialização do componente (
: oaplicativo de exemplo de componente está hospedado no GitHub Pages. O site é carregado rapidamente graças à pré-geração estática usando o projeto GitHub mantido pelaaplicativo de exemplo para BlazorWasmPrerendering.Build
comunidade.- Pré-geração ao integrar componentes em Razor aplicativos Pages e MVC
-
Controlar
Upload de arquivos: enviar arquivos para um servidor com renderização do lado do cliente (CSR)
Autenticação e autorização
- Mitigação de ameaças do lado do servidor: XSS (script entre sites)
- Blazor Visão geral de segurança do lado do servidor
-
Blazor cenários adicionais do lado do servidor: Lendo tokens de
HttpContext
- Blazor WebAssembly Visão geral: Pré-geração de suporte
- Blazor WebAssembly cenários adicionais
- Renderização interativa do lado do servidor: XSS (script entre sites)
Gerenciamento de estado: Tratar a pré-renderização: além da seção Tratar a pré-renderização, várias das outras seções do artigo incluem comentários sobre a pré-renderização.
Para .NET 7 ou anterior, consulte Blazor WebAssembly cenários adicionais de segurança: Pré-geração com autenticação. Depois de exibir o conteúdo nesta seção, redefina a lista suspensa do seletor de versão do artigo de documentação para a versão mais recente do .NET para garantir que as páginas de documentação carreguem para a versão mais recente em visitas subsequentes.