Introduction
On my last journal, you have explored the technical side of how does it work underneath, now what you will need is how to choose between them. I'll give you 4 metrics and some use cases to help you decide.
These metrics will generally work for most of the cases but there might be some cases that are not fit with this metric.
Prerequisites
This post will not cover the technical difference between Client-Side Rendering, Server-Side Rendering, Static Site Generator, and Incremental Static Regeneration.
You are encouraged to read my journal about Understanding Next.js Data Fetching (CSR, SSR, SSG, ISR) first.
Something to note
Please do note that when we are talking about a website, you can use more than 1 fetch method. Use the necessary fetch method for each page.
Review
Let's review the last journal to remember what are the characteristics of each.
- Client-Side Rendering (useEffect) → the data is fetched after every single render
- Server-Side Rendering → the data is fetched before every single render
- Static Site Generator → the data is fetched once at build time
- Incremental Static Regeneration → the data is fetched once on build time and will be fetched again after a certain cooldown and served on the second visit.
Keep an eye on the frequency of each fetch method.
Metrics
Usually, when I'm deciding what fetch method I should use, I consider these 4 metrics.
Metric 1: 🔄 Data Integrity
Data integrity is how fresh do you want the data to be.
High
High integrity means that we want fresh data—the most updated one—every single render. This is usually crucial for pages that are interactive and contain some critical value that can't be stale.
Simply put:
We need the most updated data, every. single. time.
Sites that benefit high data integrity:
- Products page that contains price → imagine you have a product page, and the price shown is not the most updated one. You might lose some dough.
- The comment section on Twitter → we want to see the most recent comment
- Social media → we want to see the most up-to-date content obviously.
Medium
Medium integrity means that we want to serve fresh data, but it is not much of a problem if some users get stale data.
Simply put:
We should get fresh data, but it's okay if some still see the stale one.
Sites that benefit medium data integrity:
- Journal post with CMS → you can tolerate it when someone gets the stale page with minor typos
- Profile page → it is rarely updated and it is not that critical
Please note that only you can decide what is critical. If you are mainly making a website to showcase your profile and portfolio with a high update rate, then it can be considered critical.
Low to none
Pages that fall into this category usually won't change or rarely change.
Simply put:
We don't really care, just fetch and show it.
Sites that benefit low to none data integrity:
- About page
- A page with fixed data that won't change → ex: a pokemon stat page (we will use this as an example later)
Table Result
As we can see on the illustration:
- High: CSR and SSR, as it fetches on every render
- Medium: ISR, we still can get the fresh data, but some user will still get the stale one
- Low to none: SSG, it is only fetched on build time
Metric 2: 🔍 SEO
SEO (Search Engine Optimization) is going to be useful when we want our content to be easily found on google and bringing in that good organic visitors.
I only have 2 categories for this, which are SEO Friendly and Not SEO Friendly.
SEO Friendly
This category is expected when we are pre-rendering the content on the website, the general difference is when we are doing pre-render, we can see the content on the page source. This type of rendering will help search engines index our page and might put us up on the SEO ranking.
SSR, SSG, ISG categorizes as SEO Friendly because the HTML is prefilled with the content without having to fetch it on the client-side.
Sites that can benefit SEO
- Shopping website → it will be great if our products show up on search engine
- Quora-type website → site that provides an answer of course relies on SEO. You probably not going to search something directly from quora or stack overflow, but you start on google.
- Social media → contents need to be able to be searched on the internet
Not SEO Friendly
It is definitely not bad. Although we don't get any content on the page source, it doesn't mean that the search engine crawler can't index your page. The search engine can still index it, but it is not as friendly as the pre-rendered pages.
CSR is categorized as Not SEO Friendly because we do not get any content until after the page renders.
Sites that don't really need SEO
- Authentication Gated Apps → things like a dashboard, premium content, or paid courses.
- Registration page
Table Result
- SEO Friendly: SSR, SSG, and ISR all have very great SEO because they pre-render the fetched content
- Not SEO Friendly: CSR is not that good because we only get the data after render
Metric 3: ⏩ Performance
Performance is whether it is loading when we visit the page or not. It should be very easy to differentiate now if you have read the first journal.
Please note that performance in this metrics strictly means to the load time before First Contentful Paint, not to be generalized to the whole application performance.
Instant
Instantly loads because the fetching does not happen when we request.
Loads before/after render
There will be a slight loading on before or after renders.
Table Result
Well, we obviously want better performance, so this is not something that you choose as the main metrics, but rather to consider.
- Instant: SSG & ISR
- Loads before/after render: CSR & SSR
Editorial
Addition by Delba de Oliveira.
This expands on how rendering/data fetching (bringing together your application code and data) affects performance
- CSR: Rendering happens on the browser, so users may see a loading spinner while the application is being rendered. The performance (initial load) depends on the size of the application and how much JS is shipped to the browser.
- SSR: Rendering happens on the server before the result is sent to the browser. There may be latency (depending on the server's location) because the request has to go to the server and back.
- SSG: Rendering happens at a built time on the server, the result is cached in CDNs closer to users. This helps improve performance because rendering happens once and the result is stored closer to users (solving latency issues).
- ISR: Rendering happens at time intervals and is cached, so it's still performant but using ISR ensures data doesn't become stale.
Metric 4: ⏰ Build Time
Build time is the amount of time it takes to build and deploy the website.
This metric is to be considered when we are generating a bunch of pages with parameters, for example, product/[name]
or pokemon/[name]
Fast (only one page)
When we are using CSR and SSR, we only build 1 page because the data won't be fetched at build time.
For example, if we are visiting /pokemon/bulbasaur
then we will take that parameter and use it to fetch it before or after render.
Slow (every single page)
When we are using SSG and ISR, we are fetching it on build time and creating a page out of the response. So if we have 1000 products, it will take quite some time.
Build Time Example
Alt:
/ssr/poke/[name]
only have 1 page even though it is serving 100 pokemon/ssg/poke/[name]
have all of the pokemon names built into a page.
This is something that you'll need to consider if you have thousands of products, or you want to show all of the pokemon out there. We can't wait for them to finish building, using CSR or SSR should be the right answer.
Cheatsheet
Examples
CSR
https://next-usecase.thcl.dev/csr
Video:
- there is a loading indicator when visited
- the data (repository detail) that is served is the most up to date
It's ideal for a dashboard and authentication-gated website. We need the latest data, and we don't really care about SEO.
SSG
I'll give SSG example first so we can compare it with SSR
https://next-usecase.thcl.dev/ssg
Video:
- Data fetched on build time at 13:58:38, when the current time is already 2 hours late—16:28:30
- It is instant and has no loading
- There are 10 pokemon data to choose
This one is great for pokemon data because the data probably won't change for quite some time. And maybe you have a question:
Why not just store it as JSON and create every page?
We usually use SSG for convenience, adding hundreds of pages is quite repetitive and we can maintain it better if we use getStaticProps
SSR
You probably notice and have it in mind that apps that have high data integrity and have a good SEO should use SSR, for example, products page, comment section. The obvious example should be Quora, Reddit, Facebook, etc.
But it is not always the case, here is the same pokemon app using SSR:
https://next-usecase.thcl.dev/ssr
Video:
- Clicking the page takes a second or two before the page shows up
- Fetch time is the current time (meaning the data is fresh)
- There are considerably a lot of pokemon to choose
This use case fits because there are about 900 pokemon, and if we build all of them using SSG, it is going to take a while. That is why you should also consider the build time metric.
Well actually 900 is not that much, but imagine Amazon or eBay.
ISR
ISR is quite fun and might be the common grounds between the 4 fetch methods, but we need to emphasize the data integrity. ISR can still give stale data, so it will be dangerous if you are using it on a critical process.
For this example, I suggest you visit it yourself
What to do:
- Try to star the repo that is linked in the demo page (disclosure: you are going to star my personal repository, kindly keep it starred if you like this post 😉)
- Wait for about 5-10 seconds
- Refresh the page twice (remember how ISR works)
Demo page: https://next-usecase.thcl.dev/isr
You done? Cool!
We can see that the data will still update, but we can have medium data integrity and still have a good performance.
This is very useful if you are creating a journal with CMS, and it will be updated without having to rebuild the whole site.
Additional Resource
There is a pattern that uses ISR and SWR library, it follows optimistic UI by mutating the value, and regenerating on the background.
I'm not going to cover this topic, but Joe Bell has a really great article about it.
Conclusion
Save the 4 metrics cheatsheet, and try to consider each of them when you want to choose.
Remember you can use multiple fetch methods on different pages. You can use CSR on the dashboard, and also use SSR on the product page. Use the best one.