What is the RSC?


React Server Components The React Server Components team released a solution to the React page’s performance issues with multiple interface requests. Of course, the proposal is still in the draft stage, and the official only released a video and a sample demo to illustrate the draft.

The React Server Component is a way to write a React Component that is rendered on the Server side to improve the performance of the React application.

RSC background?


The main reason is that a lot of React components rely on data requests before rendering. If this is the case, then if each component requests data by itself, the sub-component will wait for the parent component to complete the data request and only start to request the data of the sub-component when rendering the sub-component, which is the official so-called WaterFall data request queue. Putting data requests together is very difficult to maintain. A dilemma arises.

How does the RSC solve the problem of component dependence on data rendering?


Since components rely on data for rendering. So why doesn’t the interface just return the rendered component? So they came up with the Server Components solution. The React component is divided into two types: Server component (.server.tsx) and Client component (.client.tsx). The Server component is rendered directly on the Server side and returned.

What is the difference between RSC and SSR?


When rendering on the server side, you will think about SSR, which makes no difference. Compare SSR to render components on the server side as HTML strings filled with content and used behind client hydrate. Server Components are more like normal Components written on the client side, except that they run on the Server side.

SSR is associated with initialization

With SSR, you render the HTML and send it to the client, then load the React JS. Once the JS is loaded, the application reverts back to the client’s React application, which is “hydrated”.

That means that SSR’s application is not the old application SSR owns after initialization, and in SSR, all your components are still client components, except that your first page load is pure HTML!

The RSC is always on the server side

The React Server component is always rendered on the Server. These might be components that fetch some data from the back end, so it makes sense to juxtapose the presentation of these components with the data being fetched. Whenever these components need to be rerendered, they are reextracted from the server and merged into the existing client-side React component tree. The cool thing is that even if we retrieve parts of the view from the server, the client state remains.

RSC components are more likely to reduce package sizes

Because SSR applications are all about initial page loading, clients may end up downloading all the dependencies as they browse your application. For RSC components, these dependencies will always exist only on the Server, because React Server components will not be delivered to the front end before rendering.

How to use RSC


Website Demo

RSC advantage


Nature is closer to the back end

Comparisons are returned to the client after being rendered by the server. Any other data source can be plugged into the ServerComponent simply by encapsulating the API provided by React to support Suspense. Nature is closer to the back end.

To solve the waterfall

The RSC is passed to the client as a stream

0 packing volume

That might be ideal, or it might be ok in some scenarios. Why? As an example, suppose we develop an MD editor. The server passes a string in the MD format to the front end.

We need to introduce a library on the front end to parse MD into AN HTML string. This library has 206K.

import marked from 'marked'; // 35.9k (11.2kgzipped) import sanitizeHtml from 'sanitize-html'; // 206K (63.5k gzipped) function NoteWithMarkdown({text}) {const HTML = sanitizeHtml(marked(text)); return (/* render */); }Copy the code

Simply mark NoteWithMarkdown as ServerComponent and put the logic to import and parse MD on the server side. That is, putting it on the server side doesn’t require the client to go to the bundle to reduce the size of the package.

Automatic code segmentation

Dynamic import of components can be implemented using react. lazy.

Previously, this had to be done manually when we switched components/routes. In ServerComponent, this is all done automatically.

Reduce client rendering stress

Like SSR, load -> get data -> render, such a serial mode, into a server operation in parallel mode, to reduce the client rendering pressure.

Possible problems with the RSC


Interface to return

Normal: The component is loaded, the interface returns the data required by the component, and the view is updated and rendered.

RSC: The combination of component loading and data loading reduces the bundle’s volume, but this disadvantage is more obvious when the volume is escaped to the interface return, especially in paged requests such as lists. Components only need to be loaded initially, but because they are merged into the interface, each time the interface returns a redundant component structure, it is not known whether it is good or bad. Maybe you need to optimize the interface later to return only data twice.

Server cost

Moving the client rendering behavior to the server inevitably increases the pressure on the server side, and the cost of this area increases by an order of magnitude as the number of users increases. The official response to this question is that as the cost of servers decreases, the advantages of Server Components will offset this disadvantage. For now, that is expensive.

Is there a better solution to the problem solved by the RSC?


The RSC solves the problem of interface requests being scattered among components causing data requests from child components to wait for the parent component request to finish rendering the child component before the request can begin.

In fact, there is, that is in the writing of the optimization, for example:

import React, {useState, useEffect} from 'react';
import ReactDOM from 'react-dom';

function App() {
  const [data, setData] = useState([]);
  useEffect(() => {
    fetchData.then(setData);
  }, []);
  
  return (
    <div>
      {!data.length ? 'loading' : null}
      <Child data={data} />
    </div>
  );
}

function Child({data}) {
  const [childData, setData] = useState([]);
  useEffect(() => {
    fetchChildData.then(setData);
  }, []);
  
  if(!data.length) {
	return null;
  }
  
  return (
    <div>{data.length + childData.length}</div>
  );
}

ReactDOM.render(<App />, document.querySelector('#root'));

Copy the code

As the sample code shows, simply loading the component but not returning the DOM in the case of no data can also make the child component’s data requested first without waiting. Of course this needs to be optimized in the way it’s written, but I still think it’s better than going through the hassle of making a Server Component.

RSC: RFC


RFC

In terms of the RFC of the RSC, there are pros and cons. Most people still frown on the Server Component, saying it probably doesn’t address real business pain points the way React Hooks do. In terms of the proposals exposed so far, I personally feel that the Server Component does more harm than good.