How to Understand React Server Components
The evolution of RSC did not happen overnight; it is more like a kind of natural selection.
Updated
Rethinking the Evolution of RSC
The evolution of RSC did not happen overnight; it is more like a kind of natural selection.
RESTful API
In the early days of the internet, pages contained relatively little content and were mostly rendered on the back end. In other words, the early way front end and back end interacted was: the back end injected data directly into the front end.
As electronic devices became more capable, network transmission efficiency improved, browser runtime performance increased, and front-end capabilities expanded, the front end took on an ever-heavier workload. The traditional front-end-first, back-end-injection approach wasted too much time, so the front end was able to split off and become a separate role.
Influenced by the REST architecture, front end and back end began to separate, entering the jQuery era.
The front end fetched data from the back end through Ajax and updated the UI through DOM manipulation. Routing was still controlled by the back end, and pages were still MPAs, or pseudo-static pages simulated by the back end.
This was an iteration of the development model: the data source shifted from being a back-end concern to a front-end concern.
The mental model of front-end development adjusted accordingly: from how to implement UI effects to how to update the UI.
The back end went from returning HTML to returning json / xml data, but the overall interface granularity still stayed at the page level.
To better adapt to this new work—the question of how to update the UI—the front end gave birth to three major frameworks: Angular, React, and Vue. The front-end mental model iterated further: how to connect state with UI.
At this level, the back end also adjusted accordingly, and RESTful APIs appeared: the back end no longer cared about the View in MVC, focusing instead on the Model and Controller. To make interfaces reusable, RESTful APIs emerged, keeping back-end modules independent and decoupled from front-end pages.
BFF
Although both front end and back end had evolved into fairly modern versions, the network communication protocol was still HTTP/1.1 from the 1990s, which made network requests very limited.
Because of RESTful's minimal modules, a single page might need to request multiple RESTful interfaces to meet its needs.
However, with HTTP/1.1, each request requires creating a TCP connection. If you add the overhead of loading static resources, the number of connections becomes very large. This is unacceptable to the operating system: it can easily overwhelm the entire TCP SYN_RECV queue, causing large numbers of pending ACCEPT requests to be rejected outright—effectively a DDoS against the operating system.
This forced browsers to limit a page to no more than 6 simultaneous requests per origin, to avoid putting too much load on the operating system; other resources could only wait in line.
On first load, a page needs to send a large number of requests, including negotiating cache validity, requesting new resources, and loading data. If CDNs can relieve the pressure of resource loading, the request inflation caused by RESTful's characteristics is hard to avoid.
Therefore, the internet evolved further and produced two solutions, HTTP2 and BFF:
- HTTP2 is a complete reconstruction at the network layer, allowing requests with the same five-tuple to reuse the same TCP connection without repeated handshakes.
- BFF is more of a transitional solution, advocating a BFF layer between RESTful and the front end, aggregating the data a page uses on the server side and returning it to the front end in one shot.
HTTP2 depends on implementations in browsers, servers, and so on, and it is not friendly to self-signed certificates; in some scenarios it is hard to enable HTTP2 requests with self-signed certificates.
For backward compatibility, most companies still choose BFF; the only question is who maintains this BFF layer.
In the early days, aggregation was indeed done by the back end. With the rise of NodeJS, front-end aggregation solutions gradually appeared, especially GraphQL, which further reduced the maintenance difficulty of BFF.
The mental model iterated once again: the front end began to take over some simple back-end work, such as CRUD.
RSC
As front-end content kept growing, first screens became increasingly bloated and the required vendors grew larger, so more and more companies chose to embrace SSR / SSG. Facts have shown that MPA still has its advantages, especially in first-screen performance.
Considering that GraphQL essentially calls different policies according to a DSL and returns different content, the returned content is not actually restricted, which means: an interface does not necessarily have to return interface data.
This is very important. Given the growing popularity of SSR, if you destroy an entire component, fetch new VDOM or HTML directly from an interface, and mount it in place of the original node, then—assuming the interface request stays the same—does that mean this VDOM or HTML can also be cached?
Which also means that, for back-end data, this is a significant way to relieve pressure.
So RSC emerged as the times required. And not just RSC: Astro's island architecture and Web Components were also created or flourished against the same background.