en
· 4 min de leitura

UI com streaming e o que ela custa para o backend

Streaming faz a página parecer rápida. Também mantém conexões abertas, multiplica queries e esconde caminhos lentos. Orce isso.

fullstacknextjs

Streaming é a melhor coisa que aconteceu com renderização no servidor em uma década. A casca da página chega em cem milissegundos, as partes lentas preenchem conforme resolvem, e o usuário começa a ler antes de o banco terminar de pensar. Uso em quase todo produto que construo.

Mas streaming move custo, não remove. O frontend parece mais rápido porque o backend faz o mesmo trabalho em outro formato, e esse formato tem consequências que ninguém coloca na demo.

A conexão fica aberta

Um render tradicional segura a conexão pelo tempo da query mais lenta e depois envia tudo de uma vez. Um render com streaming segura pelo mesmo tempo, mas o primeiro byte sai imediatamente. O tempo total de conexão por requisição não cai. O que muda é que o usuário percebe como rápido.

Isso importa para capacidade. Se o seu painel de recomendações leva três segundos e você faz streaming dele, toda visualização de página mantém uma conexão aberta por três segundos e pouco. Seu reverse proxy, seu load balancer e seu runtime serverless têm limites de conexões abertas simultâneas, e um componente lento em streaming transforma um problema de throughput em um problema de concorrência.

Já vi um time fazer streaming de um painel lento para consertar uma nota de Core Web Vitals e depois bater no limite de requisições simultâneas da plataforma numa terça à tarde. A nota subiu. O site caiu. O painel eram os mesmos três segundos de qualquer jeito.

Suspense boundaries se multiplicam

Cada Suspense boundary é uma promise que o servidor está esperando. Coloque cinco em uma página e o servidor roda cinco caminhos de dados independentes para cada requisição. Antes do streaming, aquela página faria uma ou duas queries em sequência. Depois, faz cinco em paralelo, e cada uma segura uma conexão do pool do banco.

Paralelo é bom para latência e ruim para pools. Um pool de vinte conexões com cinco queries por visualização satura com quatro usuários simultâneos. Eu confiro o tamanho do pool contra o número de boundaries por rota em toda auditoria, e a conta está errada com mais frequência do que certa.

A defesa é a mesma de sempre: deduplique as leituras, cacheie o que não muda e dê a cada boundary uma query que seja rápida sozinha. Um componente em streaming que roda uma query sem índice continua sendo uma query sem índice. Só que agora tem um spinner.

Caminhos lentos se escondem melhor

O custo mais sutil é observabilidade. Quando a página renderizava como uma unidade, uma query lenta deixava a página inteira lenta e alguém percebia. Com streaming, a casca é rápida, a métrica que todo mundo olha parece boa, e o painel de três segundos fica invisível nos dashboards porque o time to first byte não o inclui mais.

Então eu instrumento por boundary. Cada componente assíncrono reporta a própria duração com a rota e o nome do boundary anexados. O alerta é sobre o boundary mais lento, não sobre a página. Senão o streaming vira um jeito de esconder regressões atrás de um skeleton.

Erros precisam do mesmo tratamento. Um boundary que lança exceção renderiza o fallback de erro e o resto da página fica bem, o que é o comportamento certo para o usuário e o errado para o engenheiro de plantão se ninguém logou. Todo fallback de erro reporta antes de renderizar.

Onde o streaming paga o próprio custo

Streaming vale a pena quando uma página tem uma ou duas partes lentas e não críticas e uma casca sobre a qual o usuário pode agir imediatamente. Uma página de produto com cabeçalho rápido e seção de avaliações lenta. Um dashboard onde o resumo está em cache e o detalhe é ao vivo.

Não vale a pena quando toda parte da página é lenta, porque aí você está só pagando o custo da conexão para mostrar um skeleton por três segundos. Conserte as queries primeiro. E não vale a pena quando a parte lenta é o que o usuário veio buscar, porque uma casca rápida em volta de uma resposta lenta é um jeito rápido de decepcionar.

Desenhe o orçamento por rota: quantos boundaries, quanto o mais lento pode levar, quantas conexões isso implica no pico. Depois faça streaming. A feature é excelente. A fatura ainda chega.