Hey HN! I wanted to share an experiment I ran that tests the performance of RSC vs traditional client-side React on one of our product websites (productonboarding.com). I know RSC is a bit of a controversial topic since server-side rendering used to be an ancient paradigm with the shift to modern JS frameworks. As such, I went into the experiment with a healthy dose of skepticism.
To test this out, I conducted an experiment where I built an RSC version and a traditional client-side React version of the same website and measured performance. We were able to improve our bundle size and speed by 62% and 63%, respectively. You can find the whole writeup here. https://frigade.com/blog/bundle-size-reduction-with-rsc-and-...
I actually enjoyed building with RSC more than I expected to, and it made for a better user experience since it rendered almost 3x faster than the client version.
Would love to hear any feedback and thoughts on our experiment. Have you started to use React Server Components yet, or no? Have you seen similar results?
A site visit might consist of more than a single page load, and (hopefully) includes some interactions. For some sites, "client-side + HTTP data as needed" strategy will have a longer time to first render, but might be much quicker once you introduce interaction.
It doesn't look like either of your tools measures overall performance for a site visit (as I characterize it), but maybe it doesn't matter in your case. What was your thinking in this regard?
I'm assuming Gen Z? You are aware that your index.html of your React app is also server-side rendered, right? And you are aware that all the API's that your SPA talks to are also server-side rendered, right?
It’s a frequent refrain on here, whenever some post talks about doing any server rendering in a JS context, that it was done before… even well before. It’s so frequent as to be cliche, and usually rather dismissive of any actual substance to the context of whatever’s in the post.
As I read it, OP is just anticipating that reaction, acknowledging it upfront with a bit of levity.
Our site is dealing with a dynamic where our Core Web Vitals are already green, and thus our priority-setting folks don't see it as a priority to improve the score any further.
I want to be able to tell them "Hey, Green at 600ms will still give us an SEO boost over Green at 800ms, so we should do this," but I am having a hard time establishing whether that is actually true. Does anyone know for sure?
During the experiment we used Google's PageInsight which will give you a literal "Speed Index". Without RSC Google gave us a Speedindex of only 1.6 vs 0.6 with RSC, which seems to factor directly into the PageRank algorithm: https://developers.google.com/search/blog/2018/01/using-page...
There's a temptation to get caught up on quantifiable scores when working on SEO because so much of it can't be quantified, everyone is mostly guessing what Google wants... however, scores are ultimately meaningless and you should be measuring the impact on your business metrics. For example, if your website is designed to generate sales, did reducing your CWV to 800ms improve revenue? SEO is a means to an end, you can spend thousands of human hours to rank #1 for a keyword but if it doesn't improve a metric that matters (e.g: your revenue) it's a complete waste of time.
More broadly, prioritisation isn't about whether a piece of work will achieve its aim, it's about understanding which options are the best use of limited resources. For example, you may be able to say confidently that reducing CWV from 800ms to 600ms will increase your traffic from Google search by 5% but that's immaterial until it's compared against other options -- there's an opportunity cost associated with all work.
Personally, I would be surprised if reducing CWV from 800ms to 600ms is the best use of your resources, unless your business is one of the few that has a strong organic search strategy with organic search accounting for a meaningful volume of revenue -- nowadays, most companies find paid ads are much more effective.
If you want to know if those 200ms matter, try adding 200ms of artificial latency on every page load for a week and see what it does to conversions.
As a first approximation, the difference between 600ms and 800ms will probably be similar to the difference between 800ms and 1000ms. You should be able to get a rough figure of what that difference is with 1 line of change to your code.
I wonder how much overhead does the rendering or react on server add ?
If I have an API sever and then instead of calling those apis from client, I make all db calls on the server and then render the html.
How much of processing that was done was spent on rendering html.
Also I wonder how react server components and serverside rendering go with localfirst software?
I love localfirst web apps, they seem kinda incompatible with serverside apps
In either case you have database calls (when calling an API, or when rendering from server). Adding network overhead (the subsequent request for data) is the last thing I'd want, if I could avoid it.
That’s great. What if I don’t want to write a whole new NodeJS backend just to support SSR, when the existing backend with all our APIs that we already wrote is a Spring Boot service?
I’ve looked at Nashorn and then Graal to do this, but couldn’t find widely supported resources that work well and snap right in. Anyone in the same boat that has had success?
I also maintain a JVM which we run some backend JS libraries on via custom Nashorn builds. It's slow and drinks memory. Setting up a façade in front of a pool of ScriptEngine objects mitigates some of the startup cost, but I super don't like the idea of running React for server rendering. I would suggest standing up a NodeJS rendering microservice instead; we'd do it if arcane deployment reasons didn't preclude the possibility.
Pick up unpoly, HTMX, Hotwire, or some other hypermedia oriented library and have the Spring Boot server start rendering HTML instead of JSON
HTML templating works great, it's battle tested, typically still blows away RSC performance, and you get to keep all your mature domain logic and data layers while being able to deliver great UX with minimal client code
I must be getting older, because "everything old is new again" keeps coming to mind.
Only advice would be: don't follow these fads unless you a) are doing it to learn or b) can quantify tangible business value in the change. The worst reason to do it is because everyone else seems to be doing it*
*Unless literally everyone is doing it and the "old" thing becomes unsupported.
Unbelievable, deceptive levels of clickbait at play - they moved from a client app to a server app, so of course the initial render is faster.
This has nothing to do with RSC, and @dang /moderators should probably change the headline.
"Moving from a client-side app to a server app (using React Server Components) made our site faster" is very unsurprising, not very interesting (what would be interesting is comparison from another server rendering technique), and wouldn't have made the HN homepage likely, but they've already cheesed their way here.
Because they could have moved to a server based app not using RSC and seen similar gains, so the deception is they are trying to make it seem like RSC caused the gain (and riding on the back of a hyped new technology) whereas it's not really the case.
But RSC is how you do server based apps with React, and they’re clearly sticking with React.
Sure you can render to static markup without RSC but then you have to do a lot of work to mix server/interactive client components, RSC makes it a lot easier to achieve “server based apps”.
I think it’s less work to just use static content in places and avoid having to learn a whole new model of rendering, routing, data fetching and a lot of rules than it is to have a traditional ssr app that compiles a few static pieces of content.
RSC is how React figured out partial hydration. Before this, you would simply not move to a server-rendered app, as it was not worth it - the client bundle would stay the same and you're just increasing overhead.
Not true in the slightest. A server rendered app would deliver your html up front so your app is completely rendered immediately, this has been common for many years now and improves performance quite a bit. Couple with sending some static parts that avoid JS which is quite doable you have 90 some % of the benefit in a simpler model. That’s also why more direct a comparison of a SSR app to a RSC app is interesting.
Partial hydration is great but it’s a shame React is coupling it to a whole new routing model, component model, server rendering, and with such complex rules on use and inherent waterfalls as a side effect. There’s no reason to. You can get partial hydration any number of ways and avoid all the complexity.
> Couple with sending some static parts that avoid JS which is quite doable
If when you say "they could have moved to a server based app", you are implying that they could have done partial hydration easily some other way, that's a wild assumption. Until very recently partial hydration was not even on the table, as the community decided that downloading 10MB of JS for every website was fine, and not 'quite doable' for the majority of React apps; they are usually monolithic and built on top of frameworks that make it difficult. Not impossible (we were doing this back in 2016 with different tech), but very uncommon.
As I said above, this is exactly what RSC is solving for. It's not a new thing, but the first solution endorsed by React itself, and enabled them (and potentially all React apps) to gain SSR with partial hydration, reduce bundle sizes and actually improve load performance.
I'm not a big fan of any of this, just stating what it is. And I agree that it introduces monstrous complexity to an ecosystem that's already overflowing with it. Astro for example achieves this without introducing too many new concepts.
Totally agree that partial hydration helps more than full hydration, but note that if you compared SSR vs RSC the charts they posted wouldn't look so impressive.
Maybe I was too strong worded, but the point stands that without making it really clear they are "skipping a generation" basically, it makes their comparison look extremely favorable, whereas RSC actually has a big overhead: it serializes all props and the entire tree that's not hydrated into an arbitrary serialization format that JS then needs to parse and hydrate. They actually are far from as zero-cost as other partial hydration methods. And if you had compared SSR vs RSC you'd see that the numbers don't actually improve so much.
So is it like 10/10 deceptive? No, but it's also a meme thats going around and not the first article to try and gain attention by conveniently leaving out of the title and most of the article that 80% of the gain they got was just going from client-only to server-rendered, and not actually RSC. I absolutely stand by it being deceptive, if only on a more annoying than actually harmful level. The graphs aren't comparing SSR to RSC, they're comparing the (comparatively much, much worse) client-only to RSC.
> 80% of the gain they got was just going from client-only to server-rendered
That's what the article is about, isn't it? The gain comes from going from client-only to server-rendered. They did this using RSC. You could also do it using handlebars and jQuery if it was 2010 (with probably 100x better performance).
> if you had compared SSR vs RSC you'd see that the numbers don't actually improve so much
From the article: We saw a whopping 62% reduction in bundle size as well as as 63% improvement in Google's Speed Index. You would not get those gains by simply enabling SSR in an existing app, as the bundle size will remain the same. Unless.. you use Astro or RSC to enable SSR with partial hydration. Which is what they did.
No, speed index would go up massively. A huge amount of lighthouse improves with server rendered content.
Likewise RSC is not nearly as free as other partial hydration methods. You send a full serialized copy of the tree and props over that has to be manually de serialized. This nullifies much of the benefit. Further, you still send the large (even larger now) copy of React. This is exactly why the comparison would be interesting to see, and why I brought up my concerns - it seems people are pretty under informed about this.
I agree that's a bad choice, but it doesn't change the fact partial hydration was not available until very recently. Without Astro/RSC, you can either have SSG / SSR with large bundles, or an SPA with large bundles. These are the options.
I think their headline makes total sense. It's true after all, turns out putting most of the work on your server rather than your client is a great idea for performance.
You seem to be taking personal offense to using React Server Components for this, which is odd to me.
This is a weird take, given that RSC is generally positioned for this kind of conversion. Among others, sure, but this is definitely one. It’s not deceptive to write about using a tool for one of its explicit intended purposes.
It seems as though you’re reading this article—and apparently others on the topic—as some form of attention metric gaming combat. I think the author just, uh… wrote an article about their experience with adopting a technology.
You clearly have familiarity with the technical landscape, perhaps more than most here! And maybe I’m projecting this part, but my hunch is that (like me) you follow the space closely? If I may offer some advice, for whatever it’s worth: there’s going to be a very long tail of people coming to this, or any similar, solution with less depth of knowledge and nuance, and it might be a more enjoyable reading experience to preemptively give them some grace on that.
I feel like my comments are fine and curious who you think I'm not giving grace to, I'm not attacking anyone except the article framing itself. My only ask was that HN, which usually clarifies titles to be more accurate avoid extra hype, apply that here, as the company obviously profits at the expense of the uninformed with the title here.
If anything I'm helping people less experienced understand this. HN does this title clarification all the time for much less concrete things.
I'd ask you why you felt necessary to bring in the "weird" adjective when clearly you understand this area and exactly how the less informed may not understand those graphs and title - in this very thread many of people even seem totally confused that RSC = the only way to do server rendering = novel to React. If I can give you feedback as well, instead of trying to score a point and muddy waters, just write the improved version of what I'm saying if you feel capable of doing so.
> If I can give you feedback as well, instead of trying to score a point and muddy waters
Not trying to score anything, I just sincerely think your approach to the article and its discussion is unnecessarily combative.
> just write the improved version of what I'm saying if you feel capable of doing so.
I don’t agree with your perspective that there’s anything deceptive or untoward about the article—or its title—as presented. I don’t feel capable of rewriting that position. Cheers!
Similarly, I can't stop you from coloring my (very much benign) comments as weird, rude and combative, which I myself find rude and combative.
If you wish to engage substantively, do see the multiple confused people in this very thread that illustrate the point clearly. It's very hard to reconcile their confusion with your point that this is clear to the general audience.
Perhaps your very experience with the subject is a hindrance to seeing that. Cheers.
"We made a UI framework that slows down web sites unnecessarily... but don't worry! We've now made a massive addition to the framework to mitigate the problem of our own creation! Isn't it wonderful?"
Feels somehow akin to standing in a hole and being given a shovel to dig your way out.
It's more like "we made a UI framework that speeds up development and runtime of complex apps considerably, though it also slows down initial load of web sites... but don't worry, we have a fix".
Development? Yes. Runtime? Highly debatable. At a bare minimum there are other frameworks with a significantly better runtime performance story than React.
I feel like I am in the right place at the right time to be just so happening to be working on a better and more modern Wordpress :)
If client-side/server-side rendering with static and incremental loading, combined with dynamic markdown loading is your type of thing; please checkout my project and give me a star to follow.
Wow there's a lot of negative comments here on such a simple post along the lines of "Hey we adopted this new version of this library and it boosted our site performance x%".
I think the move React is making to embrace the server side is a great thing. It shows we pushed really hard in one direction, made great progress in building a simple and easy-to-grok front end JS library in doing so, but in the end found that the server _is_ the correct place for the majority of the processing to happen in most cases. The great thing with React Server Components is you don't have to change much about how you write react code, you can just define which specific components you need to render on the client side and boom, huge performance jump. Why is that a bad thing?
It's not that RSC is a bad thing, there's just a lot of animosity built up from years of react developers shitting on the concept of processing on servers and antagonizing the developers who work in that space.
Then, hey, it turns out those idiot backend devs that were so looked down upon may actually have known what they were doing after all.
There's also the bit where RSC seems wonderful if all you know is react but seems very mediocre if you've any significant experience with any of a number of other backend stacks
I have yet to meet a frontend dev who called a backend dev an idiot. I have met plenty of backend devs who have indirectly called frontend devs idiots.
I have to agree on this. But also anyone who calls anyone else an "idiot" for how they code is doing it wrong™. We can learn from what eachother thrive in. For backend, it's usually data structures, databases, performance, etc. while on the frontend it's creating visually appealing UIs that feel good to interact with and both of those sides of web dev act to bring people into what we create time and time again. So when backend devs get mad when frontend devs say "Hey, maybe backend isn't so bad after all", that feels backwards.
I agree as well, having worked on both sides (and "full stack"). Not really calling "idiot", but more of the bias that frontend development is easy and not "real" programming whereas I've never personally seen the reverse attitude.
I have only worked at more "traditional" companies so that likely influences my experience as well, it may be different at different kinds of companies.
61 comments
[ 1.3 ms ] story [ 300 ms ] threadTo test this out, I conducted an experiment where I built an RSC version and a traditional client-side React version of the same website and measured performance. We were able to improve our bundle size and speed by 62% and 63%, respectively. You can find the whole writeup here. https://frigade.com/blog/bundle-size-reduction-with-rsc-and-...
I actually enjoyed building with RSC more than I expected to, and it made for a better user experience since it rendered almost 3x faster than the client version.
Would love to hear any feedback and thoughts on our experiment. Have you started to use React Server Components yet, or no? Have you seen similar results?
It doesn't look like either of your tools measures overall performance for a site visit (as I characterize it), but maybe it doesn't matter in your case. What was your thinking in this regard?
I need to go lie down
I'm assuming Gen Z? You are aware that your index.html of your React app is also server-side rendered, right? And you are aware that all the API's that your SPA talks to are also server-side rendered, right?
As I read it, OP is just anticipating that reaction, acknowledging it upfront with a bit of levity.
I want to be able to tell them "Hey, Green at 600ms will still give us an SEO boost over Green at 800ms, so we should do this," but I am having a hard time establishing whether that is actually true. Does anyone know for sure?
More broadly, prioritisation isn't about whether a piece of work will achieve its aim, it's about understanding which options are the best use of limited resources. For example, you may be able to say confidently that reducing CWV from 800ms to 600ms will increase your traffic from Google search by 5% but that's immaterial until it's compared against other options -- there's an opportunity cost associated with all work.
Personally, I would be surprised if reducing CWV from 800ms to 600ms is the best use of your resources, unless your business is one of the few that has a strong organic search strategy with organic search accounting for a meaningful volume of revenue -- nowadays, most companies find paid ads are much more effective.
As a first approximation, the difference between 600ms and 800ms will probably be similar to the difference between 800ms and 1000ms. You should be able to get a rough figure of what that difference is with 1 line of change to your code.
If I have an API sever and then instead of calling those apis from client, I make all db calls on the server and then render the html. How much of processing that was done was spent on rendering html.
Also I wonder how react server components and serverside rendering go with localfirst software?
I love localfirst web apps, they seem kinda incompatible with serverside apps
This project is a marketing site, for which client-side rendering never made sense.
I’ve looked at Nashorn and then Graal to do this, but couldn’t find widely supported resources that work well and snap right in. Anyone in the same boat that has had success?
https://github.com/falsandtru/pjax-api
https://falsandtru.github.io/pjax-api/docs/modes/
HTML templating works great, it's battle tested, typically still blows away RSC performance, and you get to keep all your mature domain logic and data layers while being able to deliver great UX with minimal client code
Only advice would be: don't follow these fads unless you a) are doing it to learn or b) can quantify tangible business value in the change. The worst reason to do it is because everyone else seems to be doing it*
*Unless literally everyone is doing it and the "old" thing becomes unsupported.
This has nothing to do with RSC, and @dang /moderators should probably change the headline.
"Moving from a client-side app to a server app (using React Server Components) made our site faster" is very unsurprising, not very interesting (what would be interesting is comparison from another server rendering technique), and wouldn't have made the HN homepage likely, but they've already cheesed their way here.
Sure you can render to static markup without RSC but then you have to do a lot of work to mix server/interactive client components, RSC makes it a lot easier to achieve “server based apps”.
It’s not a deceptive headline at all.
Partial hydration is great but it’s a shame React is coupling it to a whole new routing model, component model, server rendering, and with such complex rules on use and inherent waterfalls as a side effect. There’s no reason to. You can get partial hydration any number of ways and avoid all the complexity.
If when you say "they could have moved to a server based app", you are implying that they could have done partial hydration easily some other way, that's a wild assumption. Until very recently partial hydration was not even on the table, as the community decided that downloading 10MB of JS for every website was fine, and not 'quite doable' for the majority of React apps; they are usually monolithic and built on top of frameworks that make it difficult. Not impossible (we were doing this back in 2016 with different tech), but very uncommon.
As I said above, this is exactly what RSC is solving for. It's not a new thing, but the first solution endorsed by React itself, and enabled them (and potentially all React apps) to gain SSR with partial hydration, reduce bundle sizes and actually improve load performance.
I'm not a big fan of any of this, just stating what it is. And I agree that it introduces monstrous complexity to an ecosystem that's already overflowing with it. Astro for example achieves this without introducing too many new concepts.
Maybe I was too strong worded, but the point stands that without making it really clear they are "skipping a generation" basically, it makes their comparison look extremely favorable, whereas RSC actually has a big overhead: it serializes all props and the entire tree that's not hydrated into an arbitrary serialization format that JS then needs to parse and hydrate. They actually are far from as zero-cost as other partial hydration methods. And if you had compared SSR vs RSC you'd see that the numbers don't actually improve so much.
So is it like 10/10 deceptive? No, but it's also a meme thats going around and not the first article to try and gain attention by conveniently leaving out of the title and most of the article that 80% of the gain they got was just going from client-only to server-rendered, and not actually RSC. I absolutely stand by it being deceptive, if only on a more annoying than actually harmful level. The graphs aren't comparing SSR to RSC, they're comparing the (comparatively much, much worse) client-only to RSC.
That's what the article is about, isn't it? The gain comes from going from client-only to server-rendered. They did this using RSC. You could also do it using handlebars and jQuery if it was 2010 (with probably 100x better performance).
> if you had compared SSR vs RSC you'd see that the numbers don't actually improve so much
From the article: We saw a whopping 62% reduction in bundle size as well as as 63% improvement in Google's Speed Index. You would not get those gains by simply enabling SSR in an existing app, as the bundle size will remain the same. Unless.. you use Astro or RSC to enable SSR with partial hydration. Which is what they did.
Likewise RSC is not nearly as free as other partial hydration methods. You send a full serialized copy of the tree and props over that has to be manually de serialized. This nullifies much of the benefit. Further, you still send the large (even larger now) copy of React. This is exactly why the comparison would be interesting to see, and why I brought up my concerns - it seems people are pretty under informed about this.
The article is about a mostly-static marketing page.
You seem to be taking personal offense to using React Server Components for this, which is odd to me.
You clearly have familiarity with the technical landscape, perhaps more than most here! And maybe I’m projecting this part, but my hunch is that (like me) you follow the space closely? If I may offer some advice, for whatever it’s worth: there’s going to be a very long tail of people coming to this, or any similar, solution with less depth of knowledge and nuance, and it might be a more enjoyable reading experience to preemptively give them some grace on that.
If anything I'm helping people less experienced understand this. HN does this title clarification all the time for much less concrete things.
I'd ask you why you felt necessary to bring in the "weird" adjective when clearly you understand this area and exactly how the less informed may not understand those graphs and title - in this very thread many of people even seem totally confused that RSC = the only way to do server rendering = novel to React. If I can give you feedback as well, instead of trying to score a point and muddy waters, just write the improved version of what I'm saying if you feel capable of doing so.
Not trying to score anything, I just sincerely think your approach to the article and its discussion is unnecessarily combative.
> just write the improved version of what I'm saying if you feel capable of doing so.
I don’t agree with your perspective that there’s anything deceptive or untoward about the article—or its title—as presented. I don’t feel capable of rewriting that position. Cheers!
If you wish to engage substantively, do see the multiple confused people in this very thread that illustrate the point clearly. It's very hard to reconcile their confusion with your point that this is clear to the general audience.
Perhaps your very experience with the subject is a hindrance to seeing that. Cheers.
"We made a UI framework that slows down web sites unnecessarily... but don't worry! We've now made a massive addition to the framework to mitigate the problem of our own creation! Isn't it wonderful?"
Feels somehow akin to standing in a hole and being given a shovel to dig your way out.
I feel like I am in the right place at the right time to be just so happening to be working on a better and more modern Wordpress :)
If client-side/server-side rendering with static and incremental loading, combined with dynamic markdown loading is your type of thing; please checkout my project and give me a star to follow.
https://github.com/elegantframework/elegant-cli
I think the move React is making to embrace the server side is a great thing. It shows we pushed really hard in one direction, made great progress in building a simple and easy-to-grok front end JS library in doing so, but in the end found that the server _is_ the correct place for the majority of the processing to happen in most cases. The great thing with React Server Components is you don't have to change much about how you write react code, you can just define which specific components you need to render on the client side and boom, huge performance jump. Why is that a bad thing?
Then, hey, it turns out those idiot backend devs that were so looked down upon may actually have known what they were doing after all.
There's also the bit where RSC seems wonderful if all you know is react but seems very mediocre if you've any significant experience with any of a number of other backend stacks
I have only worked at more "traditional" companies so that likely influences my experience as well, it may be different at different kinds of companies.