Start Debugging

Os circuitos do Blazor Server agora se pausam sozinhos quando a aba fica ociosa

O .NET 11 Preview 7 adiciona um pacote opcional que pausa os circuitos interativos de Server quando a aba do navegador está oculta, liberando memória e conexões SignalR presas a usuários que não estão realmente ali.

O .NET 11 Preview 7 saiu em 2026-08-11 e, escondida na seção de ASP.NET Core, está a correção para um dos problemas de capacidade mais antigos do Blazor Server: um circuito que ninguém está olhando custa exatamente o mesmo que um circuito que alguém está usando. As notas de versão do ASP.NET Core Preview 7 apresentam a pausa automática, motivada pela issue dotnet/aspnetcore#64886.

Aba oculta não é aba desconectada

O Blazor Server mantém o estado de cada usuário em um circuito no servidor, e esse circuito vive enquanto a conexão SignalR existir. Quando o usuário troca para outra aba e esquece a sua, o WebSocket não fecha. Navegadores de desktop seguram essa conexão aberta por horas sem reclamar. O circuito mantém sua árvore de componentes, seu escopo de injeção de dependência, sua fila de renderização e sua vaga no seu orçamento de concorrência, tudo isso para um usuário que saiu na hora do almoço.

A pausa automática, em vez disso, se conecta ao sinal de visibilidade do navegador. Quando a aba fica oculta por um intervalo configurável, o cliente pede ao servidor para pausar o circuito, o que o libera. Quando o usuário volta, o circuito é retomado.

Como ligar

É opcional e vive em um pacote próprio:

<PackageReference Include="Microsoft.AspNetCore.Components.Server.AutoPause" />

A configuração fica pendurada no registro do modo de renderização:

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .WithBrowserOptions(options =>
    {
        options.AddAutoPause(pause =>
        {
            pause.Enabled = true; // default
            pause.HiddenDelay = TimeSpan.FromSeconds(30); // default is 2 minutes
        });
    });

O padrão de HiddenDelay é dois minutos. Baixar para 30 segundos recupera memória mais rápido, ao custo de mais idas e vindas de retomada para usuários que alternam entre abas o tempo todo.

Os casos em que ele se recusa a pausar

A engenharia interessante está no que a pausa automática se recusa a fazer. Ela adia a pausa quando um campo de texto ou um elemento contenteditable está com o foco, quando há áudio ou vídeo sem mudo tocando, quando existe uma janela de Picture-in-Picture aberta, quando um Web Lock está retido e enquanto ainda há atividade do circuito em andamento, como uma chamada de IJSRuntime ou uma transferência de stream. Ou seja: uma aba oculta que ainda está fazendo algo em nome do usuário não é puxada do chão dele.

Você pode acrescentar sua própria lógica de adiamento a partir de um inicializador JavaScript:

// wwwroot/{ASSEMBLY NAME}.lib.module.js
export function beforeWebStart(options) {
  options.circuit ??= {};
  options.circuit.circuitHandlers ??= [];

  options.circuit.circuitHandlers.push({
    onCircuitPausing: async (signal) => {
      await savePendingWork(signal);
    },
  });
}

O signal é abortado se a pausa for cancelada, por exemplo porque a aba voltou a ficar visível enquanto seu handler ainda salvava. No lado do servidor, Circuit.RequestCircuitPauseAsync agora retorna Task<bool> e aceita um token de cancelamento opcional, então o trabalho de adiamento pode ser cancelado quando a conexão cai.

O que verificar antes de habilitar

A pausa automática se apoia na infraestrutura de pausar e retomar introduzida no .NET 10, o que significa que a retomada reconstrói o circuito a partir do estado persistido dos componentes. Tudo o que um componente guarda em um campo comum, e nunca declara como persistente, some depois de uma pausa. Audite seus componentes com estado antes de ligar isso em produção e acompanhe sua telemetria de reconexão: o modo de falha aqui se parece muito com um circuito que se desconectou sozinho.

O Preview 7 é uma versão cheia. O lado de C# ganhou break e continue com rótulo na mesma entrega.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Voltar