In the beginning of every new React project, one question inevitably floats to the surface - should we use client-side rendering (CSR), server-side rendering (SSR) or generate a static site (SSG). It is a strategic decision which depends on several key factors.
But first, a quick review!
Note: Feel free to skip the review if you are already familiar with the basics of the three approaches. 🚀
create-react-app or a similar tool. When we execute the build script, what we can expect to find in our
build folder (among other things) is a relative bare-bone
Whenever someone visits our app in their browser, they would be able to only see the contents of the (almost empty)
At this point, additional data may be fetched from a server and displayed by the app, if needed.
Static site generation
By contrast, when we are creating a static site, we need all the contents and data of our app to be available upfront. The reason is that using SSG means we generate full-fledged HTML files already during the build step.
An important difference is that instead of having already generated static files, we are able to dynamically determine the content what is being served to the client. No rebuilds necessary. The trade-off is that what we gain in flexibility comes at the cost of an additional server and very possibly some added complexity compared to the other options.
Luckily, tools like NextJS do a good job of streamlining the development of React apps with SSR.
Now that we have a basic understanding of what our options are, let's take a closer look at how we can choose between them.
🔍 Search engine optimization
By contrast, with both SSR and SSG, the initial HTML files already contain meaningful content. This makes them easily crawlable and indexable by search engines. In addition, creating page-specific link previews when sharing links on social platforms, for example, is trivial with SSR and SSG while downright impossible with CSR (unless we use a service like prerender.io to generate them).
Is SEO always a must? Not every app needs to be search engine optimized. SEO might not be relevant if the entire app is behind a login, for example. In this case, the contents are only accessible to logged in users anyway so the lack of SEO is not a huge concern.
🌀 Dynamic content
The second important factor to consider is how dynamic is the content of the website we are building. One of the main drawbacks of the SSG approach is that in order to update the content of the app, we need to rebuild it. This might be perfectly fine if the app consists of mostly static content and is not frequently updated. A good use case for SSG would be a personal blog or a marketing website, for example.
However, in many cases, our applications need to be a lot more dynamic than that. Consider a dashboard app which needs to display up to date, personalised data for each user. It would be impractical to try to generate this statically. In this case opting for CSR is a much better choice. With it, we are able to fetch the necessary data for the specific user on the client, display it and seamlessly keep it up to date.
Here is another scenario. What if we are building a news site, where the content is both public and constantly updated. What if, in addition, there is some user generated content involved like comments under the articles, for example? Once again, SSG would not be ideal in this context. It would be much preferable to take advantage of SSR instead, with its ability to serve dynamic, non-stale, search engine optimized HTML files and easily reflect updates upon each request.
⌛ Initial load time
Finally, it is important to think about the ways in which we build and deploy our React apps and the added complexity or cost this might entail. Probably the simplest approach to deployment is if our app build consists of static files. This means we could directly deploy it on a CDN service and our website would be live. With both CSR and SSG this is exactly the case.
With SSR the infrastructure setup is more complex. Using this paradigm means we need a server to pre-render the page into HTML on every request. And even though services like Vercel make the deployment of NextJS apps almost seamless, it is important to keep in mind that as the number of users for our app increases, the infrastructure cost might increase with it.
Here is a quick summary for what we have discussed so far.
|Initial load time||❌||✅||✅|
So which approach should we choose? As usual, there is no one size fits all solution. The choice should always be determined by our particular use case.
There is also the possibility to mix and match these approaches for different parts of our app. If you want to give combining them a shot, NextJS is especially flexible in this respect.
Happy coding! ✨
If you found this article useful consider sponsoring my content!
Follow me on Twitter for more!