0Pricing
Vue Academy · Aula

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 chunks

Envolvendo 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 markup

Transmissã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:

  • renderToWebStream retorna uma ReadableStream; o Node usa pipeToNodeWritable
  • 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 renderToString bloqueador
  • 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

  1. Componente Vue Suspense
  2. Componentes assíncronos com defineAsyncComponent
  3. SSR em fluxo com renderToWebStream
  4. Estratégias de hidratação adiada
← Voltar para Vue Academy