Wyobraz sobie, ze zamiast wysylac caly statek kosmiczny jednym transportem, wysylasz go modul po module - kokpit natychmiast, a systemy nawigacyjne i ladownie dolatuja w tle. Dokladnie tak dziala Streaming SSR - serwer zaczyna wysylac HTML do przegladarki jeszcze zanim caly rendering zostanie ukonczony. A Edge Runtime przenosi ten proces blizej uzytkownika - jak stacje przekaznikowe rozmieszczone po calej galaktyce.
Tradycyjny SSR generuje caly HTML na serwerze, zanim wyslije go do przegladarki. Uzytkownik czeka na najwolniejszy komponent:
1// Tradycyjny SSR - uzytkownik czeka na WSZYSTKO
2// Serwer: [renderuj Header][renderuj Dane][renderuj Footer] -> wyslij calosc
3// Czas: 500ms + 2000ms + 100ms = 2600ms zanim cokolwiek zobaczy
4
5// Streaming SSR - fragmenty wysylane natychmiast
6// Serwer: [Header gotowy] -> wyslij! [Dane gotowe] -> wyslij! [Footer] -> wyslij!
7// Czas: 500ms do pierwszego fragmentu, reszta dochodzi w tleReact 18 wprowadza
renderToPipeableStream jako nastepce renderToString:1import { renderToPipeableStream } from 'react-dom/server';
2
3// Serwer Node.js z Streaming SSR
4app.get('/', (req, res) => {
5 const { pipe } = renderToPipeableStream(
6 <App />,
7 {
8 bootstrapScripts: ['/main.js'],
9 onShellReady() {
10 // Powloka (shell) gotowa - wyslij natychmiast
11 res.setHeader('Content-Type', 'text/html');
12 pipe(res);
13 },
14 onShellError(error) {
15 // Blad w krytycznej czesci - wyslij fallback
16 res.statusCode = 500;
17 res.send('<h1>Server Error</h1>');
18 },
19 onAllReady() {
20 // Wszystko gotowe (przydatne dla crawlerow/SEO)
21 },
22 onError(error) {
23 console.error('Streaming error:', error);
24 }
25 }
26 );
27});onShellReady jest wywolywany gdy glowna "powloka" strony jest gotowa - czyli wszystko poza granicami <Suspense>. Uzytkownik widzi szkielet strony natychmiast.Dla Edge Runtime (Cloudflare Workers, Vercel Edge, Deno Deploy) uzywamy
renderToReadableStream, ktore zwraca Web Streams API:1import { renderToReadableStream } from 'react-dom/server';
2
3// Edge Runtime handler
4export default async function handler(request) {
5 const stream = await renderToReadableStream(
6 <App />,
7 {
8 bootstrapScripts: ['/main.js'],
9 onError(error) {
10 console.error('Edge streaming error:', error);
11 }
12 }
13 );
14
15 return new Response(stream, {
16 headers: { 'Content-Type': 'text/html' },
17 });
18}Roznica miedzy API:
renderToPipeableStream - Node.js Streams (Node.js runtime)renderToReadableStream - Web Streams API (Edge Runtime, Deno, przegladarki)<Suspense> definiuje granice streamingu - serwer wysyla fallback i pozniej podmienia go na gotowy HTML:1function SpaceStationDashboard() {
2 return (
3 <div>
4 {/* Renderowane natychmiast - czesc "shell" */}
5 <Header title="Stacja Kosmiczna Alpha" />
6 <Navigation />
7
8 {/* Kazda sekcja streamuje sie niezaleznie */}
9 <Suspense fallback={<Skeleton type="missions" />}>
10 <MissionList /> {/* Dane laduja 800ms */}
11 </Suspense>
12
13 <Suspense fallback={<Skeleton type="crew" />}>
14 <CrewStatus /> {/* Dane laduja 1500ms */}
15 </Suspense>
16
17 <Suspense fallback={<Skeleton type="telemetry" />}>
18 <TelemetryData /> {/* Dane laduja 2200ms */}
19 </Suspense>
20 </div>
21 );
22}
23
24// Przebieg streamingu:
25// 1. [0ms] Serwer wysyla: Header + Navigation + 3x Skeleton
26// 2. [800ms] Serwer dosyla: MissionList (podmienia Skeleton)
27// 3. [1500ms] Serwer dosyla: CrewStatus (podmienia Skeleton)
28// 4. [2200ms] Serwer dosyla: TelemetryData (podmienia Skeleton)Edge Runtime to srodowisko wykonawcze dzialajace na "krawedzi" sieci (edge) - blisko uzytkownika, na serwerach CDN rozlozonych globalnie. Zamiast jednego centralnego serwera, Twoja aplikacja dziala na setkach lokalizacji:
1// next.config.js - konfiguracja Edge Runtime w Next.js
2// W pliku strony:
3export const runtime = 'edge';
4
5// Lub w route handler:
6export const runtime = 'edge';
7
8export async function GET(request) {
9 // Ten kod wykonuje sie na edge (blisko uzytkownika)
10 const userLocation = request.geo?.city || 'Unknown';
11
12 return new Response(
13 JSON.stringify({ message: 'Hello from edge!', location: userLocation }),
14 { headers: { 'Content-Type': 'application/json' } }
15 );
16}| Cecha | Node.js Runtime | Edge Runtime | |-------|----------------|--------------| | Lokalizacja | Jeden region serwera | Globalnie rozproszony | | Cold start | 200-500ms | 1-5ms | | Rozmiar bundla | Bez limitu | ~1-4MB limit | | API | Pelne Node.js API | Ograniczone (Web APIs) | | Streaming | renderToPipeableStream | renderToReadableStream | | Bazy danych | Dowolne | Edge-compatible (Planetscale, Turso) |
Streaming SSR naturalnie wspiera progressive hydration - React hydruje komponenty w miare ich pojawiania sie:
1// Schemat progressive hydration:
2// 1. Serwer streamuje HTML -> przegladarka wyswietla
3// 2. JavaScript sie laduje
4// 3. React hydruje komponenty ktore juz sa w DOM
5// 4. Nowe fragmenty HTML przychodza ze streamu
6// 5. React hydruje je natychmiast po otrzymaniu
7
8// Selective hydration - React priorytetyzuje
9// komponenty z ktorymi uzytkownik interaguje:
10function App() {
11 return (
12 <div>
13 {/* Uzytkownik kliknal tu - React hydruje to PIERWSZE */}
14 <Suspense fallback={<Skeleton />}>
15 <InteractivePanel />
16 </Suspense>
17
18 {/* To czeka w kolejce */}
19 <Suspense fallback={<Skeleton />}>
20 <HeavyDataTable />
21 </Suspense>
22 </div>
23 );
24}Streaming SSR i Edge Runtime to potezne narzedzia przyspieszajace dostarczanie aplikacji:
Streaming SSR zmienia dostarczanie aplikacji jak systemy modulowe na stacji kosmicznej - kazdy modul startuje niezaleznie, uzytkownik nie czeka na calosc.