What makes this noteworthy is that it's built on the still-heavily-WIP React Server Components ([1]), so unlike SSR frameworks, it doesn't require downloading full bundles of JS and raw data to re-render and hydrate your entire UI client-side. This is also the direction Next.js is heading ([2] and [3]), and will have significant ramifications for both architecture and performance of React applications for years to come. Here's a recent talk I gave on the general topic of partial hydration: https://www.youtube.com/watch?v=U28rjWrGVxk
I work on a no-code visual page builder for React-based sites like this (https://www.plasmic.app) - a major customer segment is headless commerce sites, so this is something we care a lot about.
The key to unlocking fast first-render is combination of streaming SSR (i.e. streaming HTML instead of just JS blobs), which is enabled by adopting Suspense (i.e. async the data fetch and stream data when available in HTML response, which then hydrates relevant component). RSC layers on top: it establishes a clear boundary between client and server logic, which enables better bundling strategies (as you highlighted), but also per-component and efficient subtree updates for subsequent interactions.
RSC is early but we've been working with the React core team on our use case and, based on the past few months of work and progress, we feel pretty confident about the direction. In particular, shifting legacy React apps towards Suspense+RSC will be a big shift for many, but we don't have that constraint.. We have the "luxury" of starting anew and we're leaning into the bleeding edge because it enables all the right primitives for commerce: fast first render, efficient updates, open space for optimizing bundles and RSC transport protocol, etc.
Not on you, but this move (to RSC) looks like an absolute mess. All you're trying to do is render some HTML, CSS, and JavaScript to the browser. This is over-engineering at its finest. Looking at the demo repo gave me the shakes.
Okay, but what problem is that solving? This all looks like a solution chasing a problem. The only concrete case I can come up with is delivering content to users with high latency issues (e.g., closest data center is too far away) or slow network speeds.
In that scenario, reducing bundle size and network requests can achieve a comparable (if not better) result while preserving code ergonomics. Speaking at least to the demo repo linked above, it looks like API ergonomics were an afterthought and pleasing the benchmark was first priority.
Server Components make server-side rendering wayyyyy easier for React developers.
With SSR today, developers need to take a `request` object and preload all the data necessary to render the page _before_ any component logic runs.
This is a huge pain because React components often have conditional branches inside them. Developers are forced to predict which branches need to have data preloaded, and then non-trivially pass the preloaded data into the component tree.
Look at how useSWR (a popular data fetching library) supports SSR...you preload the data and pass it in as "fallback" data. Notably, the fallback data is loaded BEFORE React starts running in a server-rendered environment. That's because React doesn't allow asynchronous actions during server-rendering - it must be available before React computes the initial HTML:
With React's new <Suspense>, the ugly SSR ergonomics disappear. Suspense allows data to be awaited during rendering, instead of it needing to be preloaded out-of-band.
This means that code for data loading can be contained completely within the relevant component, and not also duplicated within SSR preload functions.
(It also kills the primary use-case for useEffect(), which IMO is the least ergonomic hook.)
What's interesting is that <Suspense> solves ergonomics issues in both server- and client- environments - which muddies the answer to your question a bit...
Server Components are guaranteed to become the standard for developers who need SSR (ecommerce is certainly one use-case, since they want SEO).
Whether Server Components _also_ become the standard over Client Components remains to be seen. But that's purely a question of performance, not ergonomics. The decision may end up completely abstracted away from the developer via something like Next.js.
> Server Components are guaranteed to become the standard for developers who need SSR
I sincerely hope not. This is a serious detour from how web apps inherently work. Not good because it means people who start with React—likely a large number of devs—are not going to understand how the web works (and will potentially create destructive messes themselves later).
What you describe seems like a ton of overhead for what is effectively sending some data-populated HTML, CSS, and JavaScript back to a request. Perhaps I'm misunderstanding something (or it's just an idiosyncrasy of React).
> Not good because it means people who start with React—likely a large number of devs—are not going to understand how the web works (and will potentially create destructive messes themselves later).
You could say that about any abstraction. Frameworks, cars, etc. It couldn't be furthest from the truth.
Reducing bundle size and network requests is not always possible in todays package happy world. Someone will figure out ergonomics, maybe not through this package, but someone definitely will.
And the above solution is going to further incentivize package-happy thinking, not remove it.
And yes, you always can but that doesn't mean people will. It requires time, effort, and thought which sadly seems to be absent (or people just don't care enough to do it).
I know that sounds mean but this sort of stuff is driving web dev off a cliff unnecessarily.
For what it’s worth, 3/4 of the time I interrupt GitHub’s router for a full page load because it’s drastically faster (on my devices, on my network, YMMV of course).
To be clear, the Provider special treatment part is not something React Server Components do -- that seems specific to Hydrogen. My best guess is that this is some kind of a temporary workaround for the fact that we haven't built a "server context" concept into React yet (but it's a planned feature, as was noted in the original Server Components RFC). If something is confusing, I'm sure the team would appreciate the feedback on this issue!
+1 to what Dan said! `*Provider` handling of client components is a workaround for lack of server context right now. When server context ships, we'll migrate to it in Hydrogen.
There are several other things that are specific to Hydrogen that will likely change during the dev preview period as React introduces new features (like server context and SSR with RSC).
The key to unlocking fast first-render is combination of streaming SSR (i.e. streaming HTML instead of just JS blobs), which is enabled by adopting Suspense (i.e. async the data fetch and stream data when available in HTML response, which then hydrates relevant component). RSC layers on top: it establishes a clear boundary between client and server logic, which enables better bundling strategies (as you highlighted), but also per-component and efficient subtree updates for subsequent interactions.
RSC is early but we've been working with the React core team on our use case and, based on the past few months of work and progress, we feel pretty confident about the direction. In particular, shifting legacy React apps towards Suspense+RSC will be a big shift for many, but we don't have that constraint.. We have the "luxury" of starting anew and we're leaning into the bleeding edge because it enables all the right primitives for commerce: fast first render, efficient updates, open space for optimizing bundles and RSC transport protocol, etc.