React server components are a new(ish) feature in React allowing developers to render React components on the server and send them to the client as a formatted response that renders them into HTML. This is a change in approach from the traditional React method of client-side rendering where the server would send a blank HTML page and wait for the JavaScript to load and render the components on the client-side.
Isn’t this just server-side rendering?
Not exactly. The key difference between SSR and RSC is that with SSR, the entire page is rendered on the server and sent to the client, whereas, with RSC, only the server components are rendered on the server and sent to the client. Once the server components are hydrated on the client, they can fetch additional data and render the rest of the page as needed.
So what problems are React Server Components solving?
When a user visits an application that is made up of purely client-side rendered components, the client must download all of the Javascript necessary to build the application on the client. This results in large, unnecessary Javascript bundles and poor SEO (search engine optimization).
On the other hand, server-side rendering produces a page that is not interactive while the browser downloads the Javascript necessary to make it interactive, which results in a less-than-desirable TTI (time to interactive) score.
React server components allow the developer to determine what pieces of their application are rendered on the client or the server, therefore finding themselves as a middle-ground meant to mitigate the shortcomings of pure client-side rendering and pure server-side rendering.
How is it improving the performance of an application?
React server components aim to solve these issues by sending a fully-formed HTML response to the client, rather than sending a JavaScript bundle and relying on the client to render the HTML.
Sending a fully-formed HTML response can help reduce the time it takes for the page to load and improve the perceived performance of the website. Also, since the HTML response is smaller than the JavaScript bundle, it can help reduce the amount of data that needs to be transferred from the server to the client, which can help reduce the number of requests made to the server.
One of the benefits of this trimmed-down response is that you don’t need to send over packages to the client. For instance, if you require the date to be formatted and you have implemented a package to do so, the server components will only ship the formatted date and leave the package at the server.
This process of rendering React server components on the server and hydrating them on the client allows for faster page load times and a smoother user experience since the initial HTML is sent to the client with pre-rendered content that can be immediately displayed, and the server components can then fetch additional data and update the page without requiring a full page reload.
So let’s make everything a server component, right?
Not so fast. There are a couple of caveats to this approach. First, you don’t just get HTML; you get a specially formatted response that renders out to HTML which can harm the SEO of your application. Second, the client cannot interact with the Server Components, meaning tools like event handlers, useState, and useEffect cannot be present in a server component. Only JSON serializable structures make it to the user.
So when do I use server components?
To make the most out of React server components, it’s recommended to leverage their strengths in specific scenarios. For instance, if you have components that require data fetching or if you don’t need to use event handlers or useState, server components can provide benefits in terms of performance and maintainability. Additionally, server components can help you use third-party libraries on the server without bloating the client’s bundle size.
How does Next.js factor into this?
Next.js 13 takes this concept to another level with its new app router by making all components inside the app router server components by default while allowing the developer to opt into client components by using the ‘use client’ directive. This gives your application exceptional performance from the start while allowing the developer to determine what parts of the application get rendered to the client.
But doesn’t that hurt SEO?
As of Next.js 13.2, Vercel has added built-in SEO support with the new Metadata API for the app router that allows developers to define metadata for layouts or pages that are server components. This metadata can be used by search engines, social media platforms, and other tools to provide more information about the page to users, making it a powerful tool for the discoverability and engagement of Next.js applications.
The line between server and client is so very thin
Overall, the future of frontend development looks bright. With new technologies and frameworks emerging daily, developers have more tools than ever before. With a few caveats and limitations, React server components are poised to become a paradigm with staying power that offers a new way to render parts of your application on the server, reduce the Javascript bundle size, and improve performance all while creating an enjoyable user experience that is fast to build and easy to maintain.