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 boundary, RSC payload streaming aur zero-bundle server rendering.
React Server Components (RSC) woh components hain jo exclusively server par run hote hain â woh kabhi browser tak ship nahi hote. Woh directly databases, file systems, aur server-only secrets access kar sakte hain bina kisi client bundle cost ke. RSC output HTML nahi balki ek special wire format (RSC Payload) hota hai jo client par React component tree reconstruct karne ke liye use karta hai bina server code dobara run kiye.
Jab ek page load hota hai, server aapke Server Components run karta hai, directly async database queries, file reads, ya API calls execute karta hai. Output HTML nahi hota â yeh ek serialized React element tree (RSC Payload) hota hai ek custom streaming format mein.
Jab server ek Client Component ('use client' se marked) encounter karta hai, woh use render nahi karta. Balki, woh payload mein ek CLIENT_REFERENCE placeholder insert karta hai jisme component ka module URL aur props hote hain. Client in holes ko browser mein Client Component run karke fill karta hai.
Server RSC payload stream karta hai jaise-jaise woh har async operation complete karta hai. Client ka React runtime chunks receive karta hai aur progressively component tree build karta hai â pehle Server Component output, phir Client Component shells, phir hydration.
Client par React streamed RSC payload leta hai aur ise full component tree reconstruct karne ke liye use karta hai. Sirf Client Components hydrate hote hain (event listeners attach hote hain). Server Component output already final hota hai â client par koi re-execution nahi.
'use server' se marked functions Server Actions ban jaate hain â RPC-style functions jo client regular async functions ki tarah call kar sakta hai. Hood ke neeche, React server ko encoded arguments ke saath ek POST request bhejta hai aur naya RSC payload stream karke wapas laata hai.
File-level directive jo ek module aur uske saare imports ko Client Components mark karta hai. Ek client boundary create karta hai â saare exports hooks, event handlers, aur browser APIs use kar sakte hain.
Ek function ko Server Action mark karta hai. Client Components se network request ke zariye call kiya ja sakta hai. Function server par full server-side access ke saath run hota hai.
Server-rendered component tree describe karne wala ek compact streaming JSON-like format. Usme CLIENT_REFERENCE holes hote hain jahan client components jaane chahiye. HTML nahi hai.
Server Components kabhi client JS bundle mein nahi aate. Ek Server Component jo 500KB markdown parser import karta hai, client ko 0 bytes add karta hai.
'use client' ya 'use server' ke bina components dono contexts mein use ho sakte hain. Woh server par run hote hain jab Server Component import kare, aur client par jab Client Component import kare.
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 Components performance equation fundamentally change kar dete hain. Pehle, koi bhi component jo data fetch karta tha use fetching library, data transformation logic, aur rendering code client tak ship karne padte the. RSC ke saath, yeh sab server par rehta hai. Client sirf final rendered output plus interactive islands (Client Components) receive karta hai. Isse dramatically chhote bundles aur faster Time-to-Interactive milti hai.
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.