Next.js Incremental Static Generation (ISR) is an innovative feature that supercharges your web application's performance. In this comprehensive guide, you'll dive into ISR's power, understanding how to combine Static Site Generation (SSG) and Server-Side Rendering (SSR) for lightning-fast web experiences. Discover the benefits, from rapid page loads to SEO advantages. With real-world use cases, optimization tips, and troubleshooting insights, this guide equips readers to harness ISR's full potential, transforming the way they build dynamic web applications.
What is Server-side rendering?
In order to grasp the significance of Incremental Static Generation (ISR), it's essential to first comprehend the concept of server-side rendering. Prior to the advent of Next.js, most React-based applications rendered content on the client side. This meant that when a web crawler visited the site, it encountered empty or incomplete content, which posed challenges for SEO and indexing.
Why do we need Server-side rendering?
The limitation of crawlers not being able to access content poses a significant challenge for SEO. Any publicly accessible website aims to provide search engines with fully-rendered content. That's where Next.js introduced Server-side Rendering (SSR) as a solution. SSR allows pages to be rendered while they are being served, avoiding client-side rendering. By using functions like getStaticProps and getStaticPaths, Next.js empowers developers to specify how pages should be rendered on the server side. Moreover, you can continue to leverage React's lifecycle hooks to render content and fully harness its capabilities on the client side.
What is Server-side generated pages?
When working with Next.js or frameworks like Gatsby, a significant advantage lies in the ability to generate all your pages in advance and serve them with remarkable speed. Since these pages are now static and require minimal resources, you can achieve impressive response times and high page speed scores. This not only enhances user experience but also contributes to improved SEO performance.
Problems with SSG and SSR
For websites with predominantly static content, employing the Static Site Generation (SSG) approach can be effective. It works well when changes are infrequent, such as adding new articles or updating content in specific articles. In such cases, rebuilding the entire website is a viable solution.
However, this approach falls short when dealing with a large number of pages. Consider the example of an e-commerce website with thousands of products; altering the price of one product would necessitate the recreation of all pages, which can be time-consuming.
As the number of pages increases, the build time increases significantly.
This is where Next.js’s Server-Side Rendering (SSR) shines. SSR provides dynamic content, enabling immediate changes when updates occur on the backend. This approach works seamlessly for websites like e-commerce stores with substantial dynamic content.
However, SSR has its own challenge: constant API calls increase resource demands. Even when the website is hosted on a Content Delivery Network (CDN), the APIs are often situated in a single geographic location, leading to latency issues.
So, how can we strike a balance between the two worlds? Next.js came up with the perfect solution: Incremental Static Generation (ISR). ISR empowers you to build the entire website but only generates pages when new content is added or updates are made. It seamlessly combines the benefits of both SSG and SSR, offering the best of both worlds.
What is Incremental Static Generation (ISR)?
Incremental Static Generation (ISR) in Next.js introduces a powerful strategy that enables you to build or rebuild pages with precision, driven by a cache invalidation strategy. To illustrate, consider a scenario involving a blog. If you make edits to a blog post, such as modifying paragraphs, ISR allows you to rebuild only the specific blog details page displaying that content. There's no need to rebuild the entire website. Similarly, when you add a new article, you can simply regenerate the home page, pagination pages, and perhaps category pages, without touching articles that remain unchanged.
ISR provides flexibility in terms of cache invalidation. One approach is to set a fixed interval, ensuring that users see a refreshed version of the page after a certain time period.
In this code example, we are going to invalidate the page after every 60 seconds. So, one a busy website this can definitely save a lot of resources. However, there is another approach which is something which I like the most. We don’t revalidate the cache at fixed intervals, but we tell Next.js when to invalidate the cache. So, a new version of the page will be created only when there is a change in the article.
For this, we create a new API inside Next.js like below
Once done, we just need to send a webhook to Next.js for the revalidation of that page.
With this implementation, we maintain the efficiency of serving statically generated pages when the content remains unchanged. However, the moment any content is altered, the corresponding page is dynamically recreated, ensuring that users always see the most up-to-date version. Admittedly, this approach may require a bit more coding to establish a robust invalidation mechanism. Nevertheless, the substantial performance benefits it offers make the investment in setting it up well worth the effort.
With this approach, I've managed to achieve the best of both worlds, and the results are truly exciting. My website now boasts an exceptional page speed score, with the desktop score for the homepage soaring to a perfect 100. Even the majority of my inner pages have embraced this blazing-fast performance trend, consistently scoring around 100 as well. While there's always room for improvement in areas like code formatting and image optimization, the overall performance of these pages is nothing short of impressive.
You can find the page speed score of my website's pages below as well