Uma visão geral do Blazor

O Blazor permite construir aplicações web com C# que rodam no servidor, no navegador ou em uma combinação dos dois. Nesta visão geral, você vai ver na prática o que muda no HTML, na rede e no SEO quando a aplicação usa SSR, Server, WebAssembly ou o modo automático do .NET 8.

A análise parte do que aparece no DevTools do navegador. Dessa forma, fica mais fácil entender as vantagens e desvantagens de cada modelo antes de escolher um deles.

eBook completo: Blazor com .NET 8

Antes de começar, vale saber que existe um material completo sobre o tema. O eBook gratuito do balta.io aprofunda os recursos do framework no .NET 8, com exemplos práticos.

Clique aqui para baixar seu eBook

Entendendo as segmentações do Blazor

No artigo sobre o futuro do ASP.NET e Blazor, você conheceu os conceitos de SPA, SSR e WASM. Agora, o objetivo é ver com mais detalhes como o framework trata cada um desses itens.

Em outras palavras, você vai comparar na prática uma aplicação WebAssembly com uma aplicação Server ou SSR. Para isso, o foco fica em três pontos: o HTML recebido, as requisições de rede e o comportamento da página.

Segundo as novidades do ASP.NET Core no .NET 8, o framework passou a ser uma solução full stack de interface web. Ou seja, cada página ou componente pode adotar uma forma diferente de renderização.

A documentação lista quatro modos principais:

  • Static Server, também chamado de static SSR, que gera HTML estático no servidor.
  • Interactive Server, que gera componentes interativos no servidor com o modelo Server.
  • Interactive WebAssembly, também chamado de CSR, que renderiza os componentes no cliente.
  • Por fim, o Interactive Auto, que começa no servidor e depois passa para o WebAssembly.

Além disso, os modos interativos fazem pré-renderização por padrão. Então, mesmo um componente interativo chega ao navegador já com HTML pronto na primeira requisição.

Blazor SSR e Server

Quando você serve uma aplicação Blazor do lado do servidor, o comportamento inicial é parecido nos dois modos. O servidor renderiza a página por completo e a entrega pronta ao navegador.

Primeira requisição e HTML completo

Ao abrir a página inicial, o navegador faz a requisição e recebe o documento inteiro. A imagem abaixo mostra esse primeiro carregamento na aba de rede do DevTools.

Aba de rede do DevTools mostrando o carregamento inicial de uma aplicação Blazor Server com o documento HTML completo
O primeiro acesso baixa o documento inteiro, como em qualquer aplicação web.

Esse comportamento acontece em praticamente todas as aplicações em um primeiro momento, e no modelo SSR ou Server não é diferente. Como o conteúdo veio do servidor, todo o HTML da página já está inserido no documento.

Código fonte da página inicial renderizada no servidor, com cabeçalho e corpo preenchidos
O código fonte da página já contém o cabeçalho e o corpo com o conteúdo final.

O trecho que mais interessa, além do cabeçalho, é o corpo da página. Nesse exemplo, ele contém o seguinte HTML:

<h1>Hello, world!</h1>

Welcome to your new app.
</article></main></div>

Esse conjunto de cabeçalho e corpo facilita a indexação da aplicação pelos mecanismos de busca. Por isso, o SEO tende a funcionar bem nesse cenário.

Interatividade do Blazor Server com SignalR

O próximo teste é clicar no botão Click me da página Counter, que incrementa o número exibido acima dele. A imagem mostra o resultado.

Página Counter do Blazor Server com o contador incrementado sem recarregar a página
O contador muda na tela sem nenhum carregamento visível.

Nesse momento, não há carregamento, nem loading, nem nada. Na prática, a página sequer pisca.

Isso ocorre porque, no modelo Blazor Server, os componentes ficam interativos depois que a página termina de carregar. Assim, o clique no botão apenas troca dados com o servidor.

De fato, o servidor incrementa o contador e devolve o valor atualizado, mas todo o processamento acontece do lado do servidor. Para isso, as aplicações Blazor Server mantêm uma conexão aberta via SignalR, que transporta as mensagens entre navegador e servidor.

Impacto no SEO

Repare que, embora a tela tenha mudado, o HTML por baixo dela continua igual. A imagem a seguir mostra o código fonte depois do clique.

Código fonte da página Counter mostrando o valor zero mesmo após o clique no botão
O código fonte continua mostrando o valor inicial do contador.

Na seção que interessa, o texto Current count: continua com o valor 0:

<h1>Counter</h1>

<p role="status">Current count: 0</p>

<button class="btn btn-primary">Click me</button></article></main></div>
        <!--Blazor:{"prerenderId":"896ed21729c044739ddfbefcddc7d428"}-->

Esse é o comportamento normal de cenários SPA, nos quais o JavaScript gera o HTML dinamicamente. Por isso, o conteúdo gerado dessa forma não aparece em Exibir código fonte da página, o que afeta o SEO.

Ainda assim, você pode forçar a renderização completa da página quando necessário. Então, a decisão depende do que a aplicação precisa naquele momento.

Blazor WASM

Na outra ponta está o Blazor WASM, ou Blazor WebAssembly, que permite rodar o .NET e o C# diretamente no navegador. Nesse caso, a renderização acontece no cliente.

Não há como discutir a performance de interação do WASM em relação ao Server. Afinal, a máquina do usuário processa todo o conteúdo localmente, sem ida e volta ao servidor a cada clique.

O ponto que merece discussão são as desvantagens em relação ao outro modelo. E elas começam pelo tamanho da aplicação.

O tamanho da aplicação

Ao iniciar uma aplicação WebAssembly, a aba de rede revela arquivos que não existiam no modelo Server.

Aba de rede do DevTools com o download do arquivo dotnet.runtime ao iniciar uma aplicação Blazor WASM
O download do runtime do .NET aparece logo na inicialização.

O destaque é o arquivo dotnet.runtime, que faz o .NET rodar dentro do navegador. Ou seja, antes de exibir a interface, o navegador precisa baixar o runtime e os assemblies da aplicação.

Além disso, o conteúdo visual da página é igual ao que você viu no modelo Server. Para o usuário, a tela parece a mesma.

Página inicial de uma aplicação WebAssembly com o mesmo visual do modelo Server
Visualmente, a aplicação WebAssembly é idêntica à versão Server.

O HTML de uma SPA no Blazor WASM

A maior diferença está por baixo dos panos, no HTML, onde aparece o comportamento padrão de qualquer SPA. Nesse modelo, o documento inicial é básico, feito para carregar o mais rápido possível.

Depois disso, o Blazor WASM troca o miolo da página sem recarregá-la. A imagem mostra o código fonte resultante.

Código fonte de uma aplicação Blazor WASM com o corpo praticamente vazio e apenas o indicador de carregamento
No WebAssembly, o código fonte traz apenas a estrutura de carregamento.

O corpo da página fica praticamente em branco, e o resultado é apenas este HTML:

<div id="app">
    <svg class="loading-progress">
        <circle r="40%" cx="50%" cy="50%" />
        <circle r="40%" cx="50%" cy="50%" />
    </svg>
    <div class="loading-progress-text"></div>
</div>

Não importa qual página você acesse nem quantos componentes renderize na tela. No modelo WASM puro, o HTML de origem será sempre este, e por isso o SEO fica prejudicado.

Blazor Auto

Embora você possa escolher entre SSR, Server ou WASM, o .NET 8 trouxe um novo modo chamado automático. Nele, o Blazor decide se usa WebAssembly ou Server para cada componente ou página.

Isso mesmo, você pode fazer essa escolha por componente ou por página. Para isso, você usa a diretiva @rendermode com o valor InteractiveAuto.

A mágica do render mode Auto

Quando uma página ou componente usa a renderização automática, o framework considera duas coisas. Primeiro, os componentes WebAssembly respondem mais rápido porque rodam localmente.

Por outro lado, o WebAssembly demora mais na primeira renderização, por causa do download do runtime do .NET. Então, o modo Auto renderiza o componente pela primeira vez no servidor, com o modelo Server.

Enquanto o usuário interage normalmente com esse componente, uma tarefa em segundo plano baixa o runtime do .NET e o pacote da aplicação. Segundo a documentação de render modes, esses arquivos ficam em cache para as visitas seguintes.

Na próxima vez que o framework renderizar o componente, o runtime já estará disponível, e o Blazor aproveita toda a performance do WASM. É uma saída inteligente para manter performance e usabilidade, e para você basta trocar uma linha de código.

A documentação faz uma ressalva importante: o modo Auto nunca troca dinamicamente o render mode de um componente que já está na página. Ele toma a decisão inicial e mantém o mesmo tipo de interatividade enquanto o componente estiver na tela.

Como aplicar o render mode

Na prática, a configuração fica no arquivo Program.cs e no próprio componente. Primeiro, a aplicação precisa registrar os dois tipos de interatividade:

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode();

Em seguida, o componente declara o modo desejado com a diretiva @rendermode. O exemplo abaixo segue o modelo da documentação oficial:

@page "/render-mode-auto"
@rendermode InteractiveAuto

<button @onclick="UpdateMessage">Click me</button> @message

@code {
    private string message = "Not updated yet.";

    private void UpdateMessage()
    {
        message = "Somebody updated me!";
    }
}

A documentação também alerta que componentes no modo Auto precisam ficar no projeto cliente, cujo nome termina em .Client. Afinal, esse projeto configura o host WebAssembly que roda no navegador.

Comparando os modos de renderização

Depois dos testes, fica mais fácil comparar os modelos lado a lado. A tabela resume o que você observou no DevTools e o que a documentação descreve.

Modo Onde renderiza Interativo HTML no código fonte Primeiro carregamento
Static SSR Servidor Não Completo Leve
Interactive Server Servidor Sim, via SignalR Completo na pré-renderização Leve
Interactive WebAssembly Cliente Sim Estrutura de carregamento no WASM puro Mais pesado
Interactive Auto Servidor, depois cliente Sim Completo na pré-renderização Leve, com download em segundo plano

Note que a pré-renderização muda bastante o resultado para SEO. Por isso, um componente interativo em uma Blazor Web App ainda entrega HTML útil na primeira requisição.

Qual modo do Blazor escolher

Não existe um modo melhor para todos os casos, e a escolha depende do tipo de página. Páginas de conteúdo, como blog e institucional, se beneficiam do static SSR, porque entregam HTML completo e indexável.

Telas muito interativas, como painéis administrativos, funcionam bem com o Interactive Server. No entanto, esse modelo exige uma conexão constante com o servidor e consome recursos dele para cada usuário conectado.

O WebAssembly é ideal quando a aplicação precisa funcionar offline ou reduzir a carga no servidor. Por exemplo, um PWA se beneficia bastante desse modelo, apesar do download inicial maior.

Também vale considerar a hospedagem. Uma aplicação WebAssembly standalone pode ser publicada como arquivos estáticos, enquanto os modos Server e Auto exigem um servidor ASP.NET Core em execução.

Além disso, nada impede combinar modos na mesma aplicação. Por exemplo, as páginas públicas podem usar static SSR, e apenas a área logada pode adotar um modo interativo.

Já o Auto equilibra os dois mundos, com início rápido e interação local depois. Para aprofundar cada opção, leia também o artigo sobre render modes no Blazor.

Conclusão

Nesta visão geral, você viu como o Blazor se comporta em cada modelo de renderização. No SSR e no Server, o HTML chega completo, e a navegação aprimorada evita recarregar a página inteira.

No Server interativo, a conexão via SignalR atualiza a tela sem alterar o HTML de origem. Já no WebAssembly, o runtime do .NET roda no navegador, ao custo de um download maior e de um HTML inicial vazio.

Por fim, o modo Auto do .NET 8 combina o melhor dos dois, começando no servidor e migrando para o cliente. Com esses conceitos claros, você consegue escolher o modo certo do Blazor para cada página da sua aplicação.

FAQ

Qual a diferença entre Blazor Server e Blazor WebAssembly?

No Server, os componentes rodam no servidor e conversam com o navegador via SignalR. No WebAssembly, o navegador baixa o runtime do .NET e os componentes rodam no próprio navegador.

O Blazor WebAssembly é ruim para SEO?

Sem pré-renderização, sim, porque o HTML de origem traz apenas a estrutura de carregamento. Com pré-renderização no servidor, o conteúdo já chega pronto aos buscadores.

O que é a Enhanced Navigation?

É a navegação aprimorada do .NET 8, que intercepta a troca de página, faz um fetch e aplica a resposta no DOM sem recarregar a página.

O modo Auto troca de Server para WebAssembly no meio do uso?

Não. Segundo a documentação, o modo Auto decide no início e mantém o mesmo tipo de interatividade enquanto o componente estiver na página.

Posso misturar modos de renderização na mesma aplicação?

Sim. A partir do .NET 8, cada página ou componente pode declarar o seu próprio render mode com a diretiva @rendermode.

Glossário

Termo Significado
SPA Single Page Application, aplicação que troca o conteúdo da página sem recarregá-la.
SSR Server-Side Rendering, renderização do HTML no servidor antes de enviá-lo ao navegador.
WebAssembly (WASM) Formato binário que permite executar código como o runtime do .NET no navegador.
Render mode Configuração que define onde e como um componente é renderizado e se ele é interativo.
Enhanced Navigation Recurso do .NET 8 que troca de página via fetch e atualiza o DOM sem recarregamento.
SignalR Biblioteca de comunicação em tempo real usada pelo modelo Server para trocar mensagens com o navegador.
Pré-renderização Geração do HTML inicial no servidor antes de a interatividade ser ativada.
DevTools Ferramentas de desenvolvedor do navegador, usadas para inspecionar rede e código fonte.
SEO Search Engine Optimization, conjunto de práticas para melhorar a indexação nos buscadores.

Fontes