Evgenii Vedegisthoughts about software development

React server components make bundle less

Date published: January 07, 2021

React server components

A week ago, the react team posted on their blog about the new RFC So whats React Server Components?

It's components are you can run on the server. That's mean you can make yours bundle less with code splitting between front and server parts. Let's figure out what kind of components it is and how to use it.

React server components what's is this

We now have several kinds of components:

  • Client components
  • Server components
  • Hybrid components

Client components

These are the components that we are writing now, using state and effects, they allow interaction with the user and are executed in the browser. Up to this point, we only had client components. Client components are now postfixed to .client.js

Server components

These are the components that are executed on the server, they cannot use state and effects (they cannot use useState or any other hooks in client). They can be re-requested during the execution of the application. Have access to all server infrastructure. Such components are postfixed in the name .server.js. Also you can't pass functions as parameters, only data.

Hybrid components

These components can be executed both on the server and on the client. They have the strongest limitations. They cannot use client hooks and server infrastructure. In fact, they can only contain JSX markup.

How to use RSC

First to start using server components, we need to create a file with the postfix .server.js

// Note.server.js - Server Component

import db from 'db.server'
// (A1) We import from NoteEditor.client.js - a Client Component.
import NoteEditor from 'NoteEditor.client'

function Note(props) {
  const { id, isEditing } = props
  // (B) Can directly access server data sources during render, e.g. databases
  const note = db.posts.get(id)

  return (
    <div>
      <h1>{note.title}</h1>
      <section>{note.body}</section>
      {/* (A2) Dynamically render the editor only if necessary */}
      {isEditing ? <NoteEditor note={note} /> : null}
    </div>
  )
}

RSC zero-Bundle-Size Components

This is example from facebook how they're using react-server-components follow the rule zero-bundle-size.

Imagine you are writing applications to display markdown text with some lib for example: marked (my blog also works with marked btw), now you would write like this:

// NoteWithMarkdown.js
// NOTE: *before* Server Components

import marked from 'marked'; // 35.9K (11.2K gzipped)
import sanitizeHtml from 'sanitize-html'; // 206K (63.3K gzipped)

function NoteWithMarkdown({text}) {
  const html = sanitizeHtml(marked(text));
  return (/* render */);
}

In this case bundle size will add an additional 74kb, but if we transform this component with server components, we get the following:

// NoteWithMarkdown.server.js - Server Component === zero bundle size

import marked from 'marked'; // zero bundle size
import sanitizeHtml from 'sanitize-html'; // zero bundle size

function NoteWithMarkdown({text}) {
  const html = sanitizeHtml(marked(text));
  return (/* render */);
}

In this example, we changed only file name. At the same time we save 74kb by executing this part of the code on the server. Cool right?

More links:


© Copyright 2021, Evgenii Vedegis