.NET 10 - Diga adeus ao 'flash' do Blazor


     Veja como o novo atributo [PersistentState] do Blazor no .NET 10 resolve o problema da pré-renderizção do Blazor.

Se você já criou um aplicativo Blazor, conhece aquele momento. Você carrega uma página, seus dados piscam por um segundo, desaparecem e depois voltam novamente. Parece que um fantasma está assombrando sua página.



Essa é a famosa pré-renderização do Blazor que passou a ser uma marca registrada.

Os desenvolvedores tentaram corrigir isso desabilitando a pré-renderização, mas isso só tornou as coisas mais lentas e piores para o SEO.

Agora, com o .NET 10, finalmente temos uma solução real. Chama-se Persistent State Attribute, e torna seus aplicativos Blazor mais fluidos do que nunca.

O problema do 'flash' : a pré-renderização

Mas afinal o que ocorre para causar este problema do 'flash' ?

Podemos descrever isso em duas etapas:

Etapa 1: Pré-renderização no Servidor (O Setup Rápido)

O servidor executa o código do seu componente Blazor.

O Servidor constrói o HTML estático completo (incluindo seus dados) e o envia rapidamente para o navegador (o cliente). Isso é ótimo para o SEO e para a percepção de velocidade, pois o usuário vê o conteúdo instantaneamente.

Etapa 2: Hidratação no Cliente (A Reconstrução)

O Blazor é carregado no navegador e assume o controle.

O Cliente executa o mesmo código do Blazor novamente. No entanto, ele não sabe quais dados foram carregados na Etapa 1, e, assim ele faz uma nova chamada assíncrona para buscar os dados.

Enquanto espera pelos novos dados, ele substitui a visualização antiga pela nova. É nesse momento que os dados anteriores desaparecem e um novo conjunto é buscado e renderizado.

Você vê um rápido "flash" (o flicker) conforme a segunda renderização (a hidratação) substitui o HTML estático original, muitas vezes carregando dados ligeiramente diferentes (ou os mesmos, mas com um atraso perceptível).

O flash não é um bug. Ele é a falha de sincronização que ocorre porque o Blazor é executado duas vezes – uma vez no servidor para pré-renderizar (gerar HTML estático) e uma vez no cliente para hidratar (tornar o componente interativo) – mas os dados carregados na primeira vez não são persistidos ou transferidos para a segunda execução.

É aqui que o novo atributo [PersistentState] do .NET 10 entra, resolvendo essa perda de estado.

A Correção Antiga (e Por Que Prejudicava)

Antes do .NET 10, uma correção simples era desligar a pré-renderização. Isso impedia o flash, mas criava um novo problema.

Sem pré-renderização:

- A página carrega mais devagar.
- O HTML fica vazio inicialmente.
- Os mecanismos de busca não conseguem indexá-lo bem.

A Nova Correção: Persistent State

Agora existe uma maneira melhor.

O novo atributo [PersistentState] permite que o Blazor mantenha os dados que ele já criou no servidor.

Assim, quando o aplicativo carrega no cliente, ele reutiliza esses dados em vez de buscá-los novamente.

Vejamos como fazer isso na prática.

Passo 1: Crie o Projeto

Vou usar o Visual Studio 2026 (Insiders) com .NET 10 RC1. Crie um novo Blazor Web App, escolha o modo de renderização Interactive Server Render Mode (por página/componente) e pule a autenticação por enquanto.

Usaremos a página Weather padrão para testar o flash.

Passo 2: Observe o Flash

Abra o Weather.razor e certifique-se de que ele usa o modo de renderização InteractiveServer.

Execute o aplicativo e abra a página Weather.

Você verá:

- Um carregamento rápido de dados climáticos aleatórios
- Um flash
- Em seguida, um recarregamento com números diferentes

Exemplo:

  Na primeira carga   :  você vê -> 40∘F
  No recarregamento :  você vê -> 27∘F

Essa é a renderização dupla acontecendo bem diante dos seus olhos.

O Que os Desenvolvedores Faziam Antes

Para interromper isso, as pessoas costumavam desligar a pré-renderização:

@rendermode @(new InteractiveServerRenderMode(false))

Isso removia o flash, mas também removia os benefícios da pré-renderização.

Seus usuários veem uma mensagem de "Loading..." em vez de dados instantâneos.

Lição: Desligar a pré-renderização corrige o flash, mas prejudica a velocidade e o SEO.

Usando o atributo [PersistentState]

Agora vem a parte divertida.

Use o novo atributo [PersistentState] para manter seus dados ativos entre a pré-renderização e a hidratação.

No seu bloco @code:

[PersistentState]
public WeatherForecast[]? Forecasts { get; set; }

protected override async Task OnInitializedAsync()
{
   // Simula carregamento assíncrono para demonstrar renderização de streaming
   await Task.Delay(500);

   if (Forecasts is null)
   {
       // Gerando dados climáticos aleatórios...
   }
}

Isso é tudo que é preciso.

Agora o Blazor salva os dados da pré-renderização e os restaura quando o aplicativo inicia.

Recarregue sua página e olhe novamente.

Sem piscar. Sem carregamento duplo. Apenas renderização fluida.

Lidando com a Navegação da Página

Se você agora clicar entre Counter e Weather, você ainda pode ver o flash novamente.

Isso ocorre porque o Blazor não recarrega a página inteira durante a navegação interna.

A correção é fácil: adicione AllowUpdates = true.

[PersistentState(AllowUpdates = true)]
public WeatherForecast[]? Forecasts { get; set; }

Agora, mesmo quando você alterna entre as páginas, seus dados permanecem.

Agora você pode se mover entre as páginas Counter e Weather sem flash algum.

E quando a Conexão Cai ?

Se você estiver usando o Blazor Server, você conhece o circuito SignalR.

Quando a conexão cai, o circuito pausa.

Abra o console do navegador e digite:  Blazor.pauseCircuit()

Em seguida, reconecte. Você verá os mesmos dados ainda lá.

Esse é o Persistent State fazendo seu trabalho.

Ele mantém seus dados seguros durante a perda temporária de conexão.

Ajuste Fino do Comportamento

No entando o atributo [PersistentState] tem mais configurações.

Você pode decidir como o Blazor deve lidar com os dados salvos com o RestoreBehavior.

[PersistentState(AllowUpdates = true, RestoreBehavior = RestoreBehavior.SkipLastSnapshot)]
public WeatherForecast[]? Forecasts { get; set; }

As opções incluem:

 - Default: restaura tudo
 - SkipInitialValue: ignora os dados pré-renderizados na inicialização
 - SkipLastSnapshot: ignora a restauração do último estado salvo

Isso lhe dá controle sobre o quão "frescos" seus dados devem ser.

Para dashboards, você pode querer recarregar.
Para informações estáticas como resumos do tempo, você pode manter os dados salvos.

Dica: Escolha o comportamento de restauração que corresponda à experiência do usuário do seu aplicativo.

O Que Está Acontecendo nos Bastidores

Antes do .NET 10, o Blazor tinha duas fases:

1 - O Servidor constrói o HTML (pré-renderização)
2 - O Cliente executa a lógica novamente (hidratação)

Os dados entre essas duas fases eram perdidos.

Com o Persistent State, o Blazor agora salva e transfere esse estado.

Ele passa os dados já carregados diretamente para o componente hidratado.

É como encaixotar o layout da prateleira da sua loja, enviá-lo e desembalá-lo perfeitamente na chegada.

Sem esforço desperdiçado. Sem flash.

Quando É Mais Útil

O Persistent State brilha em:

- Dashboards com dados em tempo real
- Páginas de e-commerce que devem parecer profissionais
- Sites orientados por SEO que precisam de HTML estático
- Aplicativos Blazor hybrid misturando modos de servidor e cliente

Por Que Isso Importa

Este único atributo resolve uma dor de longa data para os desenvolvedores Blazor.

Você não precisa mais escolher entre um bom SEO e uma boa experiência do usuário.

Você pode ter os dois.

Se você achou este tutorial útil, visite o meu canal no Youtube onde publico vídeos duas vezes na semana abordando diversos recursos e aspectos da plataforma .NET

E estamos conversados...  

"Na verdade, na verdade vos digo que aquele que crê em mim também fará as obras que eu faço, e as fará maiores do que estas, porque eu vou para meu Pai."
João 14:12

Referências:


José Carlos Macoratti