What's the value of server-rendered React?

react
javascript

#1

I’m building a news/journalism site using React. I’ve only built purely client-rendered apps before, but I’ve been hearing a lot about server-rendered sites.

People say that server-rendering “makes sites load faster”, but wasn’t that the whole point of client-side rendering in the first place?

Eg. I’ve seen tutorials showing server-rendered apps calling third-party APIs before rendering. Surely, if the server needs to wait for a HTTP request from an API service before rendering, this will drastically slow down page loads rather than speed them up?

I can see why client-side rendering can speed up an application - only requesting a small JSON payload from the API, rather than downloading a pile of HTML and CSS, seems like it will be a lot speeder after the initial page load.

Can anyone help me understand the difference between these approaches?


#2

With regard to a news and journalism site, the greatest value of server-rendered React is likely going to be search engine optimization. While the Google crawler is able to render single-page applications, you cannot guarantee the presentation of the application reliably. For example, if you display a loading indicator before rendering a piece of content, there’s a good chance that the google bot will not see your content but rather, the loading indicator.

Furthermore, by having React generate your HTML on the server and hydrating the app on the front-end, your users will be able to see and interact with your application sooner. With this method, you could also cache the result on the server, further improving the performance of your application.

You make an excellent point about bytes transferred when you mention “only requesting a small JSON payload from the API, rather than downloading a pile of HTML and CSS”, however, unless the HTML output of your React application is abnormally large, the increase of bytes transferred should cause only a trivial decrease in performance - likely in the tens of milliseconds.

When rendering the application on the client-side and requesting data from an API there are a few things to keep in mind:

  • Assuming the API data is not personalized, you lose the ability to cache the results which results in increased server costs and performance costs
  • The requests will not go out until your application has “mounted” to the DOM if your requests are triggered in “componentDidMount”. At the very least, the client must read and parse your JS bundle before executing it.

All that said, there are ways to optimize a client-side rendered application for SEO as well as caching. An alternative to consider would be to serve your normal HTML with React app’s expected root div but also include an inlined script with any initial data you need for the app. Server to server requests will always be faster and more predictable than a client to server request. Client connections can vary from 2G to Gigabit so there’s no guarantee of performance when requesting on the client side.

I hope this helps!


#3

People say that server-rendering “makes sites load faster”, but wasn’t that the whole point of client-side rendering in the first place?

I wanted to press into these types of assertions for a moment as it’s more nuanced than simply “do it this way and it’ll be faster”.

Speaking in a very general sense, client rendered applications can be faster amortized over the lifetime of use of the app than a similar classic server-side rendered app. This is true when subsequent requests to fetch content by the client rendered app, and thus the time til readable content, are substantially smaller than subsequent requests to fetch whole pages of the server rendered app AND ALSO enough pages are viewed over time to offset the initial javascript front load of the client rendered application, not to mention the bootstrap time for the framework each time the user visits the site.

This trade-off makes client-side rendering an obvious choice for a site where a user’s average number of page views per visit is high, such as a line of business application. The trade-off does not so obviously break toward client-side rendering for a site where a user might only see a few pages per day. Perhaps a news site might fall into that category for many users.

We must also bear in mind proper caching of javascript assets and the fact that even simple changes to those assets means the user will have to download the entire asset again increasing the load time of the next page view. This is particularly true of assets that are concatenated and minimized since the slightest change to a tertiary script file that is included in the concatenated package requires the whole package to be downloaded again.

So, describing an arbitrary situation where you run a news site where the average user reads 5 articles per week and you update the site with new features or fix bugs etc and deploy, on average, once per week, 20% of the time your users will see a much slower than median time til readable content. Now, what those page load times are and the frequencies of page views and updates are going to be unique to you. But I hope this at least gives you a good framework for thinking about client-side vs classic server rendered systems.

The way I tend to think of server-rendered client-rendered systems is as a method for evening out the amortization of your time til readable content per page view over the lifetime of the use of the app, while also giving you better than average time til readable content when compared to a classic server side rendered app.

For the first page view of every visit to the site, the server renders the page and you do pull down all of the HTML content. But, generally, this content is usable/readable faster than first page view of a comparable fully client-side rendered app. After the content is usable React downloads javascript assets, on the first visit, and wires up the React app so that future requests during the visit are client-rendered and behave the same as any other client-side rendered application.

The big benefit server-side rendering of this type of app brings to time til readable content is moving asset download and framework bootstrap to after the page is usable.