NextJS practices: how to choose between CSR, SSR, SSG, and ISR

Introduction

There are basically 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.

  • Client-Side Rendering (useEffect): the data is fetched after every single render
  • Server-Side Rendering (SSR): the data is fetched before every single render
  • Static Site Generator (SSG): the data is fetched once at build time
  • Incremental Static Regeneration (ISG): the data is fetched once on build time and will be fetched again after a certain cooldown and served on the second visit.

Metrics

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. 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. We should get fresh data, but it's okay if some still see the stale one.

Sites that benefit medium data integrity:

  • Blog 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.

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

metrics table
  • 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

Metric 2: SEO

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.

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 table
  • 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

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 blog.

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

performance table

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

Few things to note:

  • 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

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.

Table Result

build time table

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.

Conclusion

final table