React Server Components (#26)
Marcus Stenbeck / December 30, 2020
5 min read
With 2020 wrapping up, I'm looking forward to the new year. I'll be creating more videos, blog posts, and courses. In the past few weeks, I've created three new videos:
- Rebuilding the Twitter Embed Widget! (Next.js + Tailwind)
- Image Component and Image Optimization with Next.js
- Internationalization (i18n) with Next.js
I also wrote a Twitter thread about React Server Components, which I'm working on turning into a blog post and video. My first attempt is the bulk of today's newsletter. Let me know what's clear, what could be improved, and what you enjoyed.
Last week, the React team announced an experimental preview of React Server Components. Server Components allow developers to build apps that span the server and client, combining the rich interactivity of client-side apps with the improved performance of traditional server rendering.
React Server Components will change how we build React applications by reducing client bundle sizes and improving boot time. Further, they will simplify data fetching and access to data sources like databases and file systems. Server Components take inspiration from existing solutions (PHP, Ruby on Rails) while providing more flexibility.
Here's why you should be excited about the future of React and the web.
Developers want to create fast applications. They need to be pragmatic about performance, without sacrificing user experience. While the promise of a silver bullet for web architecture is appealing, it's far from reality.
As web applications have matured, we've learned choosing a single rendering strategy (server-rendering or client-rendering) for your entire application isn't practical. Let's imagine rendering on the web as a bicycle with gears.
- Client-rendering is the high gear (most difficult over time).
- Server-rendering is the low gear (easier to start fast).
Pure server-rendered applications often lack a high level of interactivity. Inversely, entire client-side applications often struggle with slow boot times and large bundle sizes. React Server Components allow us to easily switch gears. You can mix server and client components, allowing you to choose the correct gear for your ride.
SSR allows you to speed up the initial, non-interactive display of client components. You still need to pay the cost of downloading, parsing, and executing those components after the initial HTML is loaded.
React Server Components are different but complementary to SSR. Server Components return a description of the rendered UI instead of HTML. This allows React to intelligently merge new data with existing client components. Server Components can also be refetched without losing the client state.
For example, let's revisit our movie page. There's a list of the cast in a movie and the ability to filter results. Each row in the list is a Server Component. When filtering the cast list, the client-side state (current search value) is not lost.
Most importantly, React Server Components allow you to choose the client or server at the component level. Next.js currently only allows access on a per-page level (e.g.
React Server Components will be incrementally adoptable with newer versions of Next.js. Any pages that use SSR will have smaller bundles and faster response times.
React Server Components use Suspense (Experimental) to allow you to wait for code to load and specify a loading state. Suspense prevents network requests from creating a waterfall.
For example, we need to fetch information about the movie (
/movie) and its cast (
/cast) for our movie page. Without Suspense, each request happens in a sequence.
With Suspense, we can make both requests without blocking our application from rendering a loading state. Suspense also helps prevent race conditions.
React Server Components are also compatible with Concurrent Mode, which lets us start rendering Client Components as their data streams in, without waiting for the entire response to finish.
Client-side rendering makes hosting React applications simple. There are many good, fast, and cheap solutions in this space.
React Server Components introduce Node.js into the mix, requiring a server or serverless hosting provider. While this does introduce more complexity for hosting, the tradeoff is better performance. Server Components allows you to use the same language, framework, and components across the full stack. Support for other backend languages (PHP, Go, Python, etc.) will come later.
React Server Components make it easier to create performant, interactive client-side solutions, keeping client-side state with fast boots from the server.
React Server Components are still experimental. Adoption will start with frameworks (e.g. Next.js). Once that's proven in production, custom setups will be more obtainable. Further, library authors will need to work on support before more extensive adoption in the ecosystem (e.g. CSS-in-JS).