Next.js SSR vs. SSG
Asked Answered
O

2

8

I am developing a Next.js e-commerce app with many pages, some of which are all-products page, specific product page, blog article page, profile page, cart page and many more. This app requires strong SEO, therefore I opted for Next.js, however, I do not have much experience with its data fetching options - SSR and SSG. I read many articles about SSR and SSG in Next.js, I am not sure if I understand it correctly though.

As I am new to this, I opted for getServerSideProps for almost all of my pages that need to load content from a RESTful API before rendering. However, I came across an article that stated that the best option for the product page is to use getStaticProps alongside with getStaticPaths with fallback = true and render a loading indicator if a certain page has not yet been pre-rendered. My app, however, changes data frequently, the database contains more than 10k products that are being removed, edited or added regularly. My first question is, whether the getStaticProps and getStaticPaths is a good option in this case. Will the product data be updated with every page view? Or do I need SSR for this? Customers always need to see the latest updates to the products. The same question goes for the all-products page, since it should only display products that are currently available and hide them as soon as they go out of stock.

My second question is about the deployment. I understand that if the app is built and exported statically, it can be deployed to static/shared hosting. However, if I use SSR in my app, I have to use a virtual server for hosting the app as far as I understand. Depending on the first question, what are the options for hosting such app?

Thank you very much for all your answers.

Optional answered 9/4, 2021 at 7:48 Comment(0)
A
12

With getServerSideProps (SSR) data is fetched at request time, so your page will have a higher Time to first byte (TTFB), but will always pre-render pages with fresh data.

With Static Generation (SSG) The HTML is generated at build time and will be reused on each request, TTFB is slower and the page is usually faster, but you need to rebuild your app every time the data is updated (can be acceptable for a blog, but not for an e-commerce).

With Incremental Static Regeneration (ISG) static content can also be dynamic, the page will be rebuilt in the background with an interval-based HTTP request. You can specify how often pages are updated with a revalidate key inside getStaticProps, this works great with fallback : true and allows you to have (almost) always updated content :

function Blog({ posts }) {
  const { isFallback } = useRouter(); // if true show loading indicator

  return (
    // your page content
  )

}

export async function getStaticPaths() {
  return {
    // no pages are generated at build time
    paths: [],
    // Enabling statically generating all pages
    fallback: true,
  }
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every second
    revalidate: 1, // In seconds
  }
}

export default Blog

Caveats : ISG is inspired by stale-while-revalidate, that means that if your pages have no visits for 1 year, even if your revalidate time is 1 second, the first user after 1 year will see 1 year old data so technically users will not always see updated data. See my answer about on-demand revalidation for more infos and resources.

next export allows you to serve the website without a node enviroment on your server (it generates statics files), see this, but is not supported by ISG and SSR

Angelia answered 9/4, 2021 at 8:58 Comment(2)
Thank you very much for your extensive answer. It is much more clear now. I will stick with server side rendering for now, seems like a more suitable option for this particular project. Thanks again!Optional
but wouldn't it regenerate the page for each request which increases server load with high traffic?Litterbug
G
3

1. The getStaticProps and getStaticPaths is a good option for this case?

Ans. getStaticProps and getStaticPaths is a good option with Incremental Static Generation for your case i.e e-commerce app.

2. Will the product data be updated with every page view?

Ans. You can pre-render the product page again after some interval. Here’s how it works:

1. Next.js can define a "timeout" for this page — let’s set it at 60 seconds.
2. The data for product Y is updated.
3. When the page for product Y is requested, the user will see the existing (out of date) page.
4. When another request comes in 60 seconds after the previous request, the user will see the existing (out of date) page. In the background, Next.js pre-renders this page again.
5. Once the pre-rendering has finished, Next.js will serve the updated page for product Y.

This approach is called Incremental Static Regeneration. To enable this, you can specify revalidate: 60 in getStaticProps

3. Where to deploy the nextjs app ?

Ans. Next.js can be deployed to any hosting provider that supports Node.js and ofcourse database for storing products data and other CRUD operations.

For reference:

  1. https://vercel.com/blog/nextjs-server-side-rendering-vs-static-generation
  2. https://nextjs.org/learn/basics/deploying-nextjs-app/other-hosting-options
Grundyism answered 9/4, 2021 at 8:41 Comment(1)
That is what I thought. I was trying to find a way to deploy the app on a shared hosting for static sites, but now I see it will not be possible. I will stick to the server side rendering for now. Thank you very much for help!Optional

© 2022 - 2024 — McMap. All rights reserved.