SSR em fluxo com renderToWebStream
renderToWebStream() versus renderToString(), fluxo HTTP, melhoria de TTFB e liberação de blocos.
SSR em fluxo com renderToWebStream é uma aula grátis de Vue Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Vue Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Vue Academy inclui 4 aulas no total.
De renderToString à transmissão
O SSR clássico usa renderToString, que monta todo o HTML na memória antes de enviar um único byte. O navegador permanece aguardando até que a página inteira esteja pronta.
O SSR por transmissão envia o HTML em fragmentos conforme o aplicativo é renderizado, para que o navegador comece a analisar o conteúdo mais cedo.
Noções básicas de renderToWebStream
O renderizador de servidor do Vue oferece funções de transmissão. renderToWebStream retorna uma ReadableStream (API de fluxos da Web), enquanto renderToNodeStream/pipeToNodeWritable têm como destino a interface de fluxos do Node.
Cada fragmento é enviado assim que a árvore de componentes é resolvida.
import { renderToWebStream } from 'vue/server-renderer'
import { createSSRApp } from 'vue'
import App from './App.vue'
const app = createSSRApp(App)
const stream = renderToWebStream(app)Enviando para uma resposta HTTP
Em um servidor Node, você envia o fluxo para a resposta. Usando pipeToNodeWritable, você escreve diretamente no fluxo gravável res, enviando os fragmentos à medida que são produzidos.
import { pipeToNodeWritable } from 'vue/server-renderer'
server.get('*', (req, res) => {
const app = createSSRApp(App)
res.write('<!DOCTYPE html><html><body><div id="app">')
pipeToNodeWritable(app, {}, res)
})Transmissão em um ambiente de execução Web/Edge
Em ambientes de execução de borda (Workers, Deno, Bun), você retorna diretamente uma Response criada a partir do fluxo da Web. Nenhum fluxo do Node é envolvido.
import { renderToWebStream } from 'vue/server-renderer'
export default async function handler(request) {
const app = createSSRApp(App)
const stream = renderToWebStream(app)
return new Response(stream, {
headers: { 'Content-Type': 'text/html' }
})
}Como os fragmentos chegam ao navegador
Enquanto o Vue renderiza os nós, ele envia strings HTML serializadas para o fluxo. A camada HTTP envia esses bytes imediatamente. O analisador incremental de HTML do navegador renderiza o conteúdo visível antes que a resposta termine.
É por isso que o usuário vê o cabeçalho e o layout enquanto o corpo da página ainda está sendo transmitido.
TTFB: a métrica principal
TTFB (tempo até o primeiro byte) mede quanto tempo leva para chegar o primeiro byte da resposta.
Com renderToString, o TTFB inclui todo o tempo de renderização. Com a transmissão, o primeiro fragmento deixa o servidor quase imediatamente, reduzindo drasticamente o TTFB e melhorando a velocidade percebida.
// renderToString: client waits for full HTML
const html = await renderToString(app) // blocks
res.end(fullPage(html))
// streaming: first bytes flush right away
pipeToNodeWritable(app, {}, res) // non-blocking chunksEnvolvendo o fluxo com o HTML do layout
Normalmente, você precisa enviar a estrutura básica do documento (<head>, tags de abertura) antes do fluxo do aplicativo e as tags de fechamento depois. Escreva o prefixo, envie o aplicativo pelo fluxo e depois escreva o sufixo quando o fluxo terminar.
res.write('<!DOCTYPE html><head><title>App</title></head>')
res.write('<body><div id="app">')
pipeToNodeWritable(app, ctx, {
write: (chunk) => res.write(chunk),
end: () => res.end('</div></body></html>')
})Tratamento de erros durante a transmissão
Depois que os bytes são enviados, você não pode alterar o código de status HTTP. Trate os erros de renderização usando a opção onError (ou o caminho de erro do fluxo gravável). Para falhas críticas detectadas cedo, prefira a renderização sem transmissão para ainda poder enviar um status 500.
pipeToNodeWritable(app, ctx, {
write: (c) => res.write(c),
end: () => res.end(suffix),
destroy: (err) => {
console.error('Stream failed:', err)
res.end() // status already sent
}
})Hidratação após a transmissão
O HTML transmitido ainda é hidratado no cliente com createSSRApp().mount(). O Vue associa ouvintes ao DOM existente em vez de recriá-lo. A transmissão afeta apenas como a marcação é entregue, não como a hidratação funciona.
// client entry
import { createSSRApp } from 'vue'
import App from './App.vue'
createSSRApp(App).mount('#app') // hydrates streamed markupTransmissão e dados assíncronos
Para componentes dependentes de dados, resolva os dados essenciais antes ou durante a transmissão. A transmissão é especialmente útil quando partes da árvore são independentes: a estrutura básica é transmitida imediatamente enquanto seções mais lentas são renderizadas conforme seus dados ficam disponíveis.
// fetch critical data, then stream the rest
const app = createSSRApp(App, { initialData })
const stream = renderToWebStream(app)
return new Response(stream, {
headers: { 'Content-Type': 'text/html' }
})Quando escolher a transmissão
Use a transmissão para páginas com muito conteúdo, nas quais o TTFB e a velocidade percebida são importantes e nas quais você pode enviar primeiro uma estrutura básica estável. Continue usando renderToString para páginas pequenas ou quando precisar de controle total sobre o código de status e os cabeçalhos finais.
Verificação rápida
Teste sua compreensão do SSR por transmissão.
Recapitulação
Você aprendeu sobre SSR por transmissão:
renderToWebStreamretorna uma ReadableStream; o Node usapipeToNodeWritable- os fragmentos são enviados conforme a árvore é renderizada, permitindo que o navegador faça uma análise incremental
- isso reduz o TTFB em comparação com o
renderToStringbloqueador - escreva a estrutura básica do documento ao redor do fluxo; erros após o primeiro envio não podem alterar o status
- a hidratação com
createSSRApp().mount()permanece inalterada
Perguntas Frequentes
A aula “SSR em fluxo com renderToWebStream” é grátis?
Sim — o texto completo de “SSR em fluxo com renderToWebStream” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Vue Academy, atualize para CoddyKit PRO. O curso de Vue Academy inclui 4 aulas no total.
O que vou aprender em “SSR em fluxo com renderToWebStream”?
renderToWebStream() versus renderToString(), fluxo HTTP, melhoria de TTFB e liberação de blocos. Você pratica Vue Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Vue Academy?
Nenhuma experiência prévia é necessária. Vue Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “SSR em fluxo com renderToWebStream”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Vue Academy?
Sim. Cada aula de Vue Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Componente Vue Suspense
- Componentes assíncronos com defineAsyncComponent
- SSR em fluxo com renderToWebStream
- Estratégias de hidratação adiada