A digest on the experimental React Server Components

In December 2020 the React team announced an experimental feature for React - React Server Components. If you want to get in the context, you can use the following resources -

Server-Side Rendering (SSR) in a nutshell (in Next.js)

  • Server injects data as Props to a page component
  • Static HTML is generated for the page and sent to the user as the response (which also has the app bundle scripts).
  • Browser renders the static HTML and starts downloading app bundle scripts (at this point, the user can not interact with the user interface).
  • Client app bundle is downloaded and re-hydrates static HTML.
  • Now users can interact with the app.

As we can see, SSR is just about generating the initial page view of a React App. The server can use cookies to identify a user and recreate the actual user interface based on the profile data or permission matrix. Frameworks like Next.js provides additional capabilities such as

  • Static site generation
  • Incremental static site generation
  • Integrated API functionality
  • Client-side routing
  • Route pre-fetching
  • Bundle splitting

With SSR, there are many code splitting strategies involved but at the end of the day, it is like all other React applications. It needs to download the vendor code, runtime, and application code to be fully functional.

Some problems that React Server Components tries to solve

Reduce bundle size

Let’s say, we use a markdown library to render some user input data, for example - this blog post.

In SSR, we can fetch the markdown data from the server and pass it to the page (which is a React component). The React component can use Remark, Marked or some other library to parse it into HTML. When the server creates the static HTML of the page, it will also create the fully parsed HTML from the markdown data.

But when the client app is downloaded, it will have the markdown parser library bundled with the app. Thus we have an additional bundle size even though we don’t need it.

React Server Components solves it by removing the component code itself. Server components will not be sent to the client-side. Instead, it will stream rendered components to the client.

Access to the back-end environment from within the React Component

In SSR (in Next.js), only the server-side props resolution function gets access to the back-end environment. The React component can only receive data from props, it has no access to the server environment.

React Server Components will allow full access to the back-end environment. As the server component will not be sent to the client, it will have access to perform any task that the back-end can perform (for example, file-system read).

Client-Server Request Waterfall

Single Page Applications (SPA) are normally paired with REST APIs. Based on the design, we might see a waterfall of network requests because each network request depends on the data of the previous network request. This is especially true when we modularize features and each feature talks to a REST Controller for data.

Facebook solves this by using GraphQL. They can request all data relative to a user in the query, thus needing only one single request to fetch all relevant data to render the user interface.

With SSR, we can fetch the data on the server-side but the data can be passed only as props to the root page component, so the components are bound to their parent components and can not be isolated.

React Server Components will be able to do what SSR does, but it can be used anywhere in the application as a component. For this, server-side operations can run at any depth of the component hierarchy.

The Abstraction Tax

React’s use of pure JavaScript allows us to create powerful abstraction with function composition, reflection. Components can also be wrapped inside other components to extend functionality. These abstractions can create a significant overhead of more code and runtime. Server components move the computation from client to server, thus offloading some critical operations to the server.

Final thoughts

React Server Components is not intended for general purpose use. It’s a new approach to solve some of the complex scenarios. It will need to integrate with routing and bundler libraries to work and existing frameworks might need to update a significant portion of the internal system to support this. But for solving some architectural problems in a complex application, developers will surely benefit from it.