Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Server-/Client-Grenze, RSC-Payload-Streaming und Zero-Bundle-Server-Rendering.
React Server Components (RSC) sind Komponenten, die ausschließlich auf dem Server laufen — sie werden nie an den Browser gesendet. Sie können direkt auf Datenbanken, Dateisysteme und serverseitige Geheimnisse zugreifen, ohne Client-Bundle-Kosten. Die RSC-Ausgabe ist kein HTML, sondern ein spezielles Wire-Format (RSC-Payload), das React auf dem Client verwendet, um den Komponentenbaum zu rekonstruieren, ohne den Server-Code erneut auszuführen.
Wenn eine Seite geladen wird, führt der Server Ihre Server-Komponenten aus und führt asynchrone Datenbankabfragen, Dateilesungen oder API-Aufrufe direkt aus. Die Ausgabe ist kein HTML — es ist ein serialisierter React-Elementbaum (der RSC-Payload) in einem benutzerdefinierten Streaming-Format.
Wenn der Server auf eine Client-Komponente trifft (mit 'use client' markiert), rendert er sie nicht. Stattdessen fügt er einen CLIENT_REFERENCE-Platzhalter im Payload mit der Modul-URL und den Props der Komponente ein. Der Client füllt diese Lücken, indem er die Client-Komponente im Browser ausführt.
Der Server streamt den RSC-Payload, sobald er jede asynchrone Operation abschließt. Reacts Client-Laufzeit empfängt Chunks und baut progressiv den Komponentenbaum auf — Server-Komponenten-Ausgabe zuerst, dann Client-Komponenten-Shells, dann Hydration.
React auf dem Client nimmt den gestreamten RSC-Payload und verwendet ihn, um den vollständigen Komponentenbaum zu rekonstruieren. Nur Client-Komponenten werden hydriert (Event-Listener angehängt). Server-Komponenten-Ausgabe ist bereits final — keine erneute Ausführung auf dem Client.
Mit 'use server' markierte Funktionen werden zu Server Actions — RPC-ähnlichen Funktionen, die der Client wie reguläre asynchrone Funktionen aufrufen kann. Intern sendet React eine POST-Anfrage an den Server mit den codierten Argumenten und streamt den neuen RSC-Payload zurück.
Direktive auf Dateiebene, die ein Modul und alle seine Imports als Client-Komponenten markiert. Erstellt eine Client-Grenze — alle Exporte können Hooks, Event-Handler und Browser-APIs verwenden.
Markiert eine Funktion als Server Action. Kann von Client-Komponenten über eine Netzwerkanfrage aufgerufen werden. Die Funktion läuft auf dem Server mit vollständigem serverseitigem Zugriff.
Ein kompaktes, streaming JSON-ähnliches Format, das den server-gerenderten Komponentenbaum beschreibt. Enthält CLIENT_REFERENCE-Lücken, wo Client-Komponenten stehen sollen. Kein HTML.
Server-Komponenten erscheinen nie im Client-JS-Bundle. Eine Server-Komponente, die einen 500KB-Markdown-Parser importiert, fügt dem Client 0 Bytes hinzu.
Komponenten ohne 'use client' oder 'use server' können in beiden Kontexten verwendet werden. Sie laufen auf dem Server, wenn von einer Server-Komponente importiert, und auf dem Client, wenn von einer Client-Komponente importiert.
1// ServerComponent.tsx — runs ONLY on server2// No bundle cost, can use async/await, access DB directly3async function ProductPage({ id }) {4 const product = await db.products.findById(id); // direct DB access!56 return (7 <div>8 <h1>{product.name}</h1>9 {/* Pass server data to a client component */}10 <AddToCartButton productId={product.id} price={product.price} />11 </div>12 );13}1415// AddToCartButton.tsx — runs on client (needs onClick)16'use client';17function AddToCartButton({ productId, price }) {18 const [added, setAdded] = useState(false);1920 return (21 <button onClick={() => {22 addToCart(productId);23 setAdded(true);24 }}>25 {added ? 'Added!' : `Add for $${price}`}26 </button>27 );28}
Server-Komponenten ändern die Leistungsgleichung grundlegend. Bisher musste jede Komponente, die Daten abrief, die Abruf-Bibliothek, die Datentransformationslogik und den Rendering-Code an den Client schicken. Mit RSC bleibt das alles auf dem Server. Der Client empfängt nur die finale gerenderte Ausgabe plus die interaktiven Inseln (Client-Komponenten). Dies führt zu dramatisch kleineren Bundles und schnellerer Time-to-Interactive.
A product detail page needs to show: product info (from DB), reviews (from API), and an interactive 'Add to Cart' button. Traditional approach: fetch all data client-side with useEffect → loading spinners → hydration overhead.
Client-side fetching means: ship the fetch logic in the bundle → render loading state → make API calls from the browser → parse responses → re-render with data. The user sees a spinner, the bundle includes API client code, and there's a waterfall: page loads → JS executes → fetch starts → data arrives.
Make ProductPage and Reviews as Server Components (the default in Next.js App Router). They fetch data on the server with direct DB/API access and send pre-rendered HTML. Only AddToCartButton is a Client Component (marked with 'use client') because it needs onClick. Zero API client code in the bundle.
Takeaway: Server Components eliminate the request waterfall by moving data fetching to the server. Only interactive components (buttons, forms, animations) need to be Client Components. This pattern typically reduces bundle size by 30-50% and eliminates loading spinners for initial data.
You're building a blog post page. It has a header (static), article body (static with syntax-highlighted code), a comment section (interactive — like/reply buttons), and a share widget (interactive — copy link, social share).
New developers often mark the entire page as 'use client' because ONE component needs interactivity. This sends the entire page's JavaScript to the browser — syntax highlighting library, markdown parser, etc. — even though 80% of the page is static content.
Keep the page as a Server Component (default). Only wrap Comment and ShareWidget with 'use client'. The header, article body, and syntax highlighting render on the server and send zero JavaScript. The client only receives the small interactive components. Think of the boundary as: 'What needs browser APIs (state, effects, event handlers)?'
Takeaway: Push the 'use client' boundary as far DOWN the tree as possible. The rule: a component should be a Client Component only if it directly uses useState, useEffect, onClick, or browser-only APIs. Everything else should stay as a Server Component for zero bundle cost.