React Server Components vs Client Components: A Detailed Discussion


This article explores the critical aspects of modern web development: User Experience (UX) and performance, focusing on the role of React Server Components (RSC). It contrasts traditional Client-Side Rendering (CSR) in React and Server-Side Rendering (SSR) in Next.js with the innovative RSC approach. RSC introduces an efficient way to separate Server and Client Components, improving loading speed, user experience, and SEO by reducing client-side JavaScript bundle sizes and improving Time To Interact (TTI). The article provides insights into how RSC works and its significant advantages over traditional rendering methods, offering React and Next.js developers a paradigm shift towards optimized web application performance.
In modern web development, User Experience (UX) and performance are critically important. Various architectures and techniques are constantly evolving to help React developers ensure these two aspects. One such significant innovation is React Server Components (RSC). In this article, we will discuss in detail what React Server Components are, how they work, and how they differ from React Client Components and traditional Server-Side Rendering (like Next.js's Pages Router). If you are a React or Next.js developer, this topic is extremely important for you.
Traditional React (Client-Side Rendering - CSR)
First, let's discuss traditional React applications, where we typically create Client Components. To understand this architecture, we need to consider the activities on both the server and client sides.
How Traditional React Works:
When you visit a webpage built using Client-Side Rendering (CSR), the following events occur:
User Request: You send a request to the server.
Server's Initial Response: The server sends you an initial HTML file along with a link to a JavaScript (JS) bundle.
Download in Browser: Your browser (on the client side) then downloads this JS bundle. The size of this bundle can be quite large, especially in complex applications (for example, in a very large application, it could be several megabytes or more, which increases loading time).
Initial Loading: The user first has to wait for the entire JS bundle to download. During this time, the user often stares at a blank screen. This is a major problem for user experience, as users might get frustrated and leave the website. Over time, as more features are added to the application, the JS bundle size increases, and the duration of this blank screen also grows.
Shell Rendering: After the JS bundle is downloaded, the React application tries to render a basic structure or "shell." At this stage, your page might become visible on the screen, but many parts might show loading indicators. This means that while the layout, like headers or footers, might be visible, the main data for the page has not yet been fetched.
Data Fetching: At this stage, your
useEffect
hooks (or other data fetching methods) execute, and components start making API calls or database queries one after another. These queries take some more time to complete on the server.Complete Rendering: After the database queries or API calls are finished, the data returns to the client, and the components re-render with that data.
Interactivity: At this point, the page is fully ready for use with data, and the user can start interacting with the website.
Disadvantages of Traditional React:
Poor SEO (Search Engine Optimization): Because the website loads slowly and initially shows a blank screen, search engine bots cannot easily crawl the content. Since most content is generated via JavaScript, SEO performance can be weak.
Poor User Experience: Users are very likely to leave the website due to prolonged blank screens or loading indicators.
Increased JS Bundle Size: As the application grows, the JS bundle size continues to increase, which further extends loading times and reduces performance.
React was an amazing library for developers because it freed them from the complexity of manually updating the DOM (Document Object Model). However, it created some limitations in terms of user experience (UX) and SEO.
Next.js and Server-Side Rendering (SSR) - Pages Router
The Next.js team saw these problems as an opportunity and optimized the traditional React architecture, especially by adding Server-Side Rendering (SSR) support in their Pages Router.
How Next.js SSR Works:
Next.js moved database queries and initial render shell tasks to the server. This means the first render of your React code happens on the server.
Database queries occur on the server, and the complete HTML for the page, along with data, is generated on the server. The server then sends this formed HTML, CSS, and necessary JS to the client.
As a result, the user no longer sees a blank screen for a long time. The First Paint happens much faster, and the user quickly sees some content, even if the data isn't fully loaded yet. This is excellent for SEO because search engine bots see content instead of a blank screen.
However, at this stage, the page is not fully interactive. That is, button clicks or other interactions will not work because client-side JavaScript is required for interactivity.
After the page becomes visible, the browser starts downloading the necessary JavaScript.
Once the JavaScript is downloaded, the Hydration process begins. Hydration is a process where React builds the client-side DOM based on the static HTML from the server and attaches event listeners (like
onClick
) to the components, making the page interactive.Only after this hydration is complete does the page become fully interactive.
Next.js SSR is much improved and faster than the previous client-side rendering method. It significantly improved First Paint and SEO, and developers could continue to work using the benefits of React.
Disadvantages of Next.js SSR:
Although Next.js SSR solved many problems, one significant issue remained. Suppose you have a page with 200 components. Among them, 150 components only display data (like text, images - these are not interactive), and the remaining 50 components are interactive (like buttons, form inputs, links). In the Next.js SSR (Pages Router model), the JavaScript for all these 200 components is sent to the client for hydration. As a result, the JS bundle size still remains quite large, and the hydration process can become slow, delaying the Time To Interact (TTI) of the page.
React Server Components (RSC) - Next.js App Router
To solve this problem, the concept of React Server Components (RSC) was introduced in Next.js 13 and the App Router.
The idea behind Server Components is quite simple. It states that when you are creating a component, you need to decide whether it will function as a Server Component or a Client Component.
How Server Components Work:
Under the Next.js App Router, all components created by default are Server Components.
If a component is a Server Component, it will only render on the server.
Importantly, the JavaScript for a Server Component is not sent to the client. This is because its rendering is completed on the server, and its result (which can be HTML, CSS, or other data structures) is streamed to the client.
Since the JS for Server Components does not reach the client, they cannot be interactive. You cannot use any client-side event handlers (like
onClick
,onChange
), state (useState
), or lifecycle effects (useEffect
) in Server Components. Attempting to do so will result in an error.If a component needs to be interactive (e.g., using state management, event handlers), it must be explicitly marked as a Client Component. This is done by using the
"use client"
; directive at the top of the file. Only the JavaScript for Client Components is sent to the client.
Through this approach, you only send the JavaScript for those components to the client that genuinely require client-side interactivity.
Advantages of Server Components:
Reduced JS Bundle Size: Since the JS for most non-interactive components (like text blocks, image displays) does not come to the client, the client-side JS bundle size is dramatically reduced.
Faster Hydration: Due to the smaller JS bundle, the hydration process for Client Components completes much faster.
Faster Time To Interact (TTI): The page becomes interactive more quickly, which improves user experience.
Improved Loading Speed and User Experience: By removing unnecessary JavaScript, the website loads much faster overall, and users can see and interact with content more quickly.
Better SEO: Faster page loads and quicker content visibility benefit search engine optimization.
Server-Side Data Fetching: Server Components can directly access databases or file systems on the server, making data fetching simpler and more secure. There's no need to send sensitive data or tokens to the client.
Practical Example:
Suppose you are creating a product card for an e-commerce website. The card contains the product's image, name, price, and an "Add to Cart" button.
In Next.js's Pages Router SSR model: The product card component would be rendered on the server and sent to the client, and its entire JavaScript would go to the client for hydration, even if only the "Add to Cart" button needed interactivity.
Using Server Components in the App Router: You can make only the "Add to Cart" button a Client Component (with the
"use client"
; directive), because only this button requires interactivity (click event, state change). The rest of the card (product image, name, price) can remain as Server Components because they only display data. As a result, instead of downloading unnecessary JS for the entire card to the client, only the necessary JS for the button will be downloaded. This reduces bundle size and improves performance.
You need to be careful when deciding which components to keep on the server and which on the client. Marking a heavy component as a Client Component unnecessarily will increase the JS bundle size and slow down the website.
Server-Side Rendering (SSR) vs. Server Components (RSC): Key Differences
Traditional Server-Side Rendering (SSR): As seen in the Next.js Pages Router, components are first rendered on the server to generate HTML. Then, that HTML and the JavaScript for all associated components are sent to the client. After the JavaScript loads on the client, React makes the page interactive through the 'hydration' process, and subsequently, components can update and re-render on the client.
React Server Components (RSC): These run only on the server, and their JavaScript code is not included in the client bundle. They handle data fetching and rendering logic on the server, and their output (which may not be direct HTML, but rather a special intermediate format that gets integrated into the Client Component tree) is sent to the client. Server Components do not hydrate on the client.
React Client Components (
"use client"
): In the App Router, Client Components can also be initially rendered on the server (if they are part of the initial page load), and then their JS is sent to the client where they hydrate and provide interactivity.
In short, SSR primarily performs initial HTML rendering on the server and then hydrates the entire application on the client. On the other hand, the RSC architecture divides components between the server and the client, where Server Components do their work solely on the server without sending their JavaScript to the client, resulting in smaller client bundles and improved performance.
Conclusion
React Server Components are a groundbreaking step in improving the performance and user experience of web applications. They give developers finer-grained control over which code runs on the server and which code is sent to the client. This prevents sending unnecessary JavaScript to the client, making applications faster, lighter, and more efficient. Although mastering this new model might take some time, its benefits are undeniable for modern web development.
Subscribe to my newsletter
Read articles from Ranjan Pal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Ranjan Pal
Ranjan Pal
I am a Web Developer and Web Designer, also i love write content regarding 'Tech' niche.