How Incremental Static Regeneration (ISR) works in NextJS

article hero image

Next.js provides the ability to create or update static pages on your site after it has been built. Incremental Static Regeneration (ISR) allows you to use static-generation on a per-page basis, meaning you don't have to rebuild the entire site each time a change is made. This approach enables you to take advantage of the benefits of static sites, such as improved performance and scalability, while still being able to update individual pages as needed. But how does it perform compared to other methods like Static-Site Generation and Server-Side Rendering? Let’s find out!

But first: What are the differences between Static-Site Generation and Server-Side Rendering and ISR?

Static site generation (SSG) and server-side rendering (SSR) are two different approaches to generating the HTML for a webpage. SSG generates the HTML at build time, which makes it easy to cache and quick to deliver. The term "static" refers to the fact that the HTML is static, but the page itself can still be dynamic, with data fetched and interactions created using client-side JavaScript. The Next.js team recommends SSG as the default choice for a variety of use cases, such as blogs, portfolio websites, e-commerce applications, and documentation websites.

On the other hand, SSR generates the HTML for a page on each request, which makes it more flexible than SSG. This means you can change the HTML without rebuilding the application each time, but it also means that performance may be impacted and it can be more difficult to cache. SSR is a good fit when SSG is not suitable, such as when you have data that is continuously updated. For example, serving the Twitter homepage as a static page would not make sense, as the content is constantly changing.

ISR is a relatively recent released feature that enables the regeneration of static pages while the site is running. In contrast to server-side rendering (SSR), where the visitor must wait for data fetching to occur before the page is generated, a fallback page is served immediately in the process of generating the page on the first request. This means that the visitor does not have to wait for data fetching to take place before being able to access the content.

Performance Aspects

Incremental Static Regeneration (ISR) can be faster than both server-side rendering (SSR) and static site generation (SSG) in certain circumstances.

With SSR, the HTML for each request is generated on the server and sent to the client, which can be slower than serving a pre-generated static HTML file. SSG pre-generates the HTML for all pages at build time, which can be faster than SSR, but the build process can take longer for sites with a large number of pages.

ISR offers the benefits of both SSG and SSR by allowing developers to generate static pages on-demand at runtime. This means that the initial request for a page can be served from a pre-generated static HTML file, while subsequent requests can be served from a dynamically regenerated version of the page. This allows for faster delivery of content while still enabling the flexibility to update pages as needed without requiring a full rebuild of the site.

As you can see the choice between using server-side rendering (SSR), incremental static regeneration (ISR), or static site generation (SSG) depends on the specific requirements and needs of the website.

How it works in Next.js

When a request is made to a pre-rendered page, the cached version of the page will be displayed initially. Any subsequent requests made to the page within the next 10 seconds will also be served from the cache, resulting in an instantaneous response. After the 10-second window has passed, the next request will still be served from the cache, but Next.js will trigger a regeneration of the page in the background. If the regeneration is successful, the cache will be invalidated and the updated page will be displayed. If the regeneration fails, the old page will remain unchanged. For pages that have not yet been generated, Next.js will server-render the page on the first request. Subsequent requests will be served from the cache, which is persisted globally by ISR on Vercel and includes rollback capabilities.

How to use ISR on your Next.js Application?

To enable Incremental Static Regeneration (ISR) on your site, you can add the revalidate prop to getStaticProps like this:

function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

// 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 10 seconds
    revalidate: 10, // In seconds
  }
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // We'll pre-render only these paths at build time.
  // { fallback: blocking } will server-render pages
  // on-demand if the path doesn't exist.
  return { paths, fallback: 'blocking' }
}

export default Blog

Source: https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration Everytime a request is made to a page that has been pre-rendered at build time, the cached version of the page will be displayed initially. Subsequent requests to the page within the next 10 seconds will also be served from the cache, resulting in an instantaneous response. After the 10-second window has passed, the next request will still be served from the cache, but Next.js will trigger a regeneration of the page in the background. If the regeneration is successful, the cache will be invalidated and the updated page will be displayed. If the regeneration fails, the old page will remain unchanged. For pages that have not yet been generated, Next.js will server-render the page on the first request. Subsequent requests will be served from the cache.

Conclusion

Ultimately, the decision of which approach to use depends on the specific needs and requirements of the website, including the amount and type of content, the level of interactivity and dynamic behavior needed, and the performance and scalability requirements. But if you aren’t sure what to use ISR may be a good could be a good compromise.