← Voltar ao blog

Streaming de HTML fora de ordem agora é nativo no navegador — sem framework

O streaming fora de ordem, popularizado pelo React Suspense, virou HTML nativo: com <template for> e marcadores de processamento, o Chrome 150 troca placeholders por conteúdo sem uma linha de JavaScript. Veja como funciona e quando adotar.

  • HTML
  • Web Platform
  • Streaming
  • Performance
  • Chrome
  • Frontend
  • SSR
Streaming de HTML fora de ordem agora é nativo no navegador — sem framework

Quem usa Next.js, Remix ou SolidStart já conhece o truque: o servidor envia o esqueleto da página imediatamente, mostra um "Carregando…" onde os dados ainda não chegaram e, quando a parte lenta fica pronta, injeta o conteúdo no lugar certo. Até agora isso dependia de JavaScript do framework rodando no cliente. Não mais: o streaming de HTML fora de ordem está chegando como recurso nativo do navegador, incorporado ao HTML Living Standard do WHATWG e já disponível no Chrome e no Edge.

O problema que isso resolve

HTML é renderizado na ordem em que chega. Se um bloco no meio da página depende de uma consulta lenta, tudo o que vem depois espera por ele. A solução de enviar primeiro o que está pronto e preencher as lacunas depois não é nova — o BigPipe do Facebook fazia isso em 2009 — e foi popularizada pelo streaming com Suspense no React. A diferença é que agora o próprio parser do navegador entende o padrão.

Como funciona a sintaxe

O recurso, que o Google chama de declarative partial updates, combina dois ingredientes: processing instructions (a sintaxe <?...> que lembra XML) para marcar pontos de inserção, e elementos <template for="nome"> que carregam o conteúdo a ser encaixado. Um par <?start name="..."> / <?end> delimita um conteúdo provisório, que é substituído quando o template correspondente chega no stream:

<ul id="results">
  <?start name="results">
  Carregando…
  <?end>
</ul>

<!-- ...mais tarde, no mesmo stream de HTML... -->
<template for="results">
  <li>Resultado 1</li>
  <?marker name="results">
</template>

<template for="results">
  <li>Resultado 2</li>
  <?marker name="results">
</template>

Repare no <?marker> dentro de cada template: ele cria um novo ponto de inserção, permitindo que a lista cresça item a item conforme o servidor envia. A escolha de processing instructions em vez de elementos comuns é intencional — elas permitem aplicar o patch sem poluir o DOM, inclusive em contextos restritos como o <head> ou o interior de uma <table>.

E do lado do JavaScript

A proposta também traz uma família de métodos de inserção de HTML — setHTML(), appendHTML(), prependHTML(), beforeHTML(), afterHTML(), replaceWithHTML() e variantes Unsafe — e versões com streaming, como streamHTMLUnsafe(). Somadas ao novo response.textStream(), elas permitem canalizar uma resposta de fetch direto para um elemento:

const feed = document.querySelector('#feed');
const response = await fetch('/api/feed-stream');

await response.textStream().pipeTo(
  feed.streamHTMLUnsafe({ runScripts: false })
);

Suporte e como começar hoje

O streaming declarativo fora de ordem está disponível no Chrome 150 e superiores, e textStream() a partir do Chrome 151. Os novos métodos de inserção estão atrás da flag de recursos experimentais e têm lançamento previsto para o Chrome 155. O WebKit publicou posição favorável ao padrão e a Mozilla sinalizou interesse, mas ainda não há data para Safari e Firefox. Enquanto isso, os polyfills template-for-polyfill e html-setters-polyfill, no npm, permitem experimentar — este último faz buffer em vez de streaming de verdade.

Para quem mantém frameworks, a novidade abre caminho para trocar runtime próprio por primitivas da plataforma. Para quem faz SSR "na mão" — em Go, PHP, Rails ou qualquer backend que consiga dar flush na resposta —, é a chance de ter a experiência de Suspense sem enviar um byte de JavaScript. Vale começar a testar agora, com o polyfill como rede de segurança, e acompanhar a chegada aos demais navegadores antes de depender disso em produção.

// COMENTÁRIOS

Deixe seu comentário

0/40
0/2000

Comentários (0)

Nenhum comentário ainda. Seja o primeiro.