0Pricing
Vue Academy · Lekcja

Strumieniowanie SSR z renderToWebStream

renderToWebStream() a renderToString(), strumieniowanie HTTP, poprawa TTFB oraz opróżnianie fragmentów.

Strumieniowanie SSR z renderToWebStream to bezpłatna lekcja Vue Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Vue Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Vue Academy zawiera 4 lekcji w sumie.

Od renderToString do strumieniowania

Klasyczne SSR używa renderToString, które buduje cały HTML w pamięci, zanim wyśle choćby jeden bajt. Przeglądarka pozostaje bezczynna do czasu przygotowania całej strony.

SSR ze strumieniowaniem wysyła HTML w fragmentach w miarę renderowania aplikacji, dzięki czemu przeglądarka wcześniej rozpoczyna analizowanie dokumentu.

Podstawy renderToWebStream

Renderer serwerowy Vue udostępnia funkcje strumieniowania. renderToWebStream zwraca ReadableStream (Web Streams API), natomiast renderToNodeStream/pipeToNodeWritable korzystają z interfejsu strumieni Node.

Każdy fragment jest wysyłany po rozwiązaniu kolejnych elementów drzewa komponentów.

import { renderToWebStream } from 'vue/server-renderer'
import { createSSRApp } from 'vue'
import App from './App.vue'

const app = createSSRApp(App)
const stream = renderToWebStream(app)

Przekazywanie strumienia do odpowiedzi HTTP

Na serwerze Node należy przekazać strumień do odpowiedzi. Za pomocą pipeToNodeWritable można zapisywać bezpośrednio do strumienia zapisywalnego res, wysyłając fragmenty w miarę ich generowania.

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)
})

Strumieniowanie w środowisku Web/Edge

W środowiskach edge (Workers, Deno, Bun) należy bezpośrednio zwrócić obiekt Response zbudowany na podstawie strumienia webowego. Strumienie Node nie są do tego potrzebne.

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' }
  })
}

Jak fragmenty docierają do przeglądarki

Podczas renderowania węzłów Vue umieszcza w strumieniu serializowane ciągi HTML. Warstwa HTTP natychmiast wysyła te bajty. Przyrostowy parser HTML przeglądarki renderuje widoczną zawartość, zanim odpowiedź dobiegnie końca.

Dlatego użytkownik widzi nagłówek i układ, gdy treść strony jest jeszcze strumieniowana.

TTFB: najważniejsza metryka

TTFB (Time To First Byte) mierzy czas do nadejścia pierwszego bajtu odpowiedzi.

W przypadku renderToString TTFB obejmuje cały czas renderowania. W przypadku strumieniowania pierwszy fragment opuszcza serwer niemal natychmiast, znacznie obniżając TTFB i poprawiając postrzeganą szybkość.

// 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

Opakowanie strumienia w kod HTML układu

Zwykle należy wysłać szkielet dokumentu (<head>, znaczniki otwierające) przed strumieniem aplikacji, a znaczniki zamykające — po nim. Należy zapisać prefiks, przekazać strumień aplikacji, a następnie zapisać sufiks po zakończeniu strumienia.

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>')
})

Obsługa błędów w trakcie strumieniowania

Po wysłaniu bajtów nie można zmienić kodu statusu HTTP. Błędy renderowania należy obsługiwać za pomocą opcji onError (lub ścieżki błędu strumienia zapisywalnego). W przypadku krytycznych błędów wykrytych odpowiednio wcześnie warto użyć renderowania bez strumieniowania, aby nadal można było wysłać kod 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
  }
})

Hydratacja po strumieniowaniu

Strumieniowany HTML jest nadal hydratowany po stronie klienta za pomocą createSSRApp().mount(). Vue dołącza listenery do istniejącego DOM-u, zamiast tworzyć go ponownie. Strumieniowanie wpływa tylko na sposób dostarczania znaczników, a nie na sposób działania hydratacji.

// client entry
import { createSSRApp } from 'vue'
import App from './App.vue'

createSSRApp(App).mount('#app') // hydrates streamed markup

Strumieniowanie i dane asynchroniczne

W przypadku komponentów zależnych od danych należy rozwiązać dane krytyczne przed rozpoczęciem strumieniowania lub w jego trakcie. Strumieniowanie sprawdza się szczególnie wtedy, gdy części drzewa są niezależne: szkielet jest strumieniowany natychmiast, a wolniejsze sekcje są renderowane po uzyskaniu danych.

// 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' }
})

Kiedy wybrać strumieniowanie

Strumieniowania należy używać w przypadku stron bogatych w treść, gdy liczą się TTFB i postrzegana szybkość oraz gdy można najpierw wysłać stabilny szkielet. W przypadku małych stron lub potrzeby pełnej kontroli nad końcowym kodem statusu i nagłówkami należy pozostać przy renderToString.

Szybki test

Sprawdź swoją wiedzę na temat strumieniowania SSR.

Podsumowanie

Dowiedział się Pan, jak działa strumieniowanie SSR:

  • renderToWebStream zwraca ReadableStream, a Node używa pipeToNodeWritable
  • fragmenty są wysyłane w miarę renderowania drzewa, dzięki czemu przeglądarka analizuje je przyrostowo
  • obniża to wartość TTFB w porównaniu z blokującym renderowaniem za pomocą renderToString
  • szkielet dokumentu należy umieścić wokół strumienia; błędy po pierwszym wysłaniu fragmentu nie mogą zmienić statusu
  • hydratacja za pomocą createSSRApp().mount() pozostaje bez zmian

Często zadawane pytania

Czy lekcja „Strumieniowanie SSR z renderToWebStream” jest bezpłatna?

Tak — pełny tekst „Strumieniowanie SSR z renderToWebStream” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Vue Academy, przejdź na CoddyKit PRO. Kurs Vue Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Strumieniowanie SSR z renderToWebStream”?

renderToWebStream() a renderToString(), strumieniowanie HTTP, poprawa TTFB oraz opróżnianie fragmentów. Ćwiczysz Vue Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Vue Academy?

Nie wymagamy żadnego doświadczenia. Vue Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Strumieniowanie SSR z renderToWebStream”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Vue Academy?

Tak. Każda lekcja Vue Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Komponent Vue Suspense
  2. Komponenty asynchroniczne z defineAsyncComponent
  3. Strumieniowanie SSR z renderToWebStream
  4. Strategie odroczonej hydratacji
← Powrót do Vue Academy