React team observes that running everything on the client can be costly, aims to fix it with Server Components

Server-side React solves 'many other problems we have had for a while' says Core developer

Facebook's React team has previewed Server Components, allowing developers to write code that runs on the server, speeding up data access and reducing the amount of code that has to be downloaded by the web browser.

Should applications run most of their code on the client, or on the server? It is a never-ending question and the balance tilts one way and then the other as technology advances. Early web applications ran mainly on the server, in part because web browsers only had basic scripting capabilities, often replacing fat native client applications for Windows or Mac. Faster connections, asynchronous JavaScript, and HTML 5 swung the pendulum back towards the client.

Then came AJAX (Asynchronous JavaScript and XML, and later the fetch API), HTML 5, and lightning-fast JavaScript. Frameworks like React.js and Angular.js made it easier to build richer browser applications, at the expense of some bloat and perhaps uglier HTML (if anyone is looking).

A new trend goes a step further and argues for static websites, built with JavaScript, that call microservices for dynamic content. JAMStack (JavaScript, APIs and Markup) site generators including Gatsby, Hugo, and Next.js create web applications that do not require a web server. Both Gatsby and Next.js use React.js so it is not either/or.

Facebook's Dan Abramov describes the benefits of having some React code run on the server instead of being downloaded to the browser

Facebook senior software engineer Dan Abramov describes the benefits of having some React code run on the server instead of being downloaded to the browser

What could go wrong? In an introduction to React Server Components, Facebook and React Core developer Dan Abramov describes what he calls the waterfall problem. This is an application that requires several different database queries to populate different components. If you grab all the data in one JavaScript fetch – he calls the example function FetchAllTheStuffJustInCase() – it is efficient, but an ugly solution, particularly if at a later date the design changes and not all the data is needed. The alternative, he said, is a separate fetch for each component, which impacts performance.

Server Components, which are in early preview, are a solution. Components with a .server.js file name run on Node.js and perform a fetch on the server, where low latency and proximity to the database server overcome performance issues. Another benefit, said Abramov, is that React libraries used in Server Components are not downloaded to the browser. In his example, he used a 21KB date library to format a date, observing that this is a heavyweight solution but since the library stays on the server, it does not matter. Components with a .client.js file name run in the browser as before. In tests, the team observed a 29 per cent reduction in the size of the bundle of JavaScript pushed to the client, when pages are converted to use Server Components, with greater reductions expected as development continues.

Server Components are not the same as server-side rendering and there are no ugly screen refreshes as users navigate a page, even if the data is re-fetched. "Server Components don't render to HTML," explained Lauren Tan, who works on React Data. "They render to a special format." The framework updates the user interface in the background. It is also possible to have files that can run either on the client or on the server. Where it runs "is determined by what kind of component that is importing that shared component," said Tan. Such components are downloaded on demand when used on the client.

An advantage of Server Components is that the code can access backend resources directly, said Abramov. Sometimes the developer might want to "read data directly, and not have to access any API layer," he said.

New libraries have been added to React to support Server Components, including react-pg for accessing a Postgres database server, react-fs for working with the file system, and react-fetch for calling APIs from the server. These are called React IO libraries.

Are Server Components replacing GraphQL, a runtime and query language used by Facebook and others? "Not really," said Abramov. "At Facebook we use both server components and GraphQL," though he added that the new components might remove the need for GraphQL in some scenarios. Server Components can read GraphQL queries.

Trying the Server Components demo with Visual Studio Code and Docker

Trying the Server Components demo with Visual Studio Code and Docker

Today many developers combine React.js or other modern JavaScript frameworks with server-side web applications. The advent of React Server Components will mean that React becomes more of a full-stack option. They "provide modern UX with a server-driven mental model," said Abramov.

The technology is still in research and development, Abramov said, and the team is working with the Next.js developers. The recommended way to get started is to download the demo and try it out; developers are discouraged from using it more widely (even though Facebook appears to be doing so). Abramov remarked mysteriously that if coders incorporate the current preview components in production, or teach about them in courses, "it makes it more difficult for us to share our research in the open." Instead, developers are encouraged to read the RFC and add their comments there.

Early reaction is mixed. "Server Components are a great idea, it will change the game," said one, while another remarked: "I wouldn't trade a fractional increase in performance for the complexity this brings to a project, especially when I have many other levers I can pull before pulling this one." ®

Keep Reading

Biting the hand that feeds IT © 1998–2021