Table of Contents
Next.js is a popular open-source framework for building server-side rendered (SSR) and static websites with React. It is built on top of Node.js and provides a robust environment for developing modern web applications.
Incremental Static Regeneration (ISR) is used in web development to enhance the performance and scalability of static websites or pages generated by static site generators. It allows for selective regeneration of specific parts of a website instead of regenerating the entire site each time new content is added or updated.
On-demand revalidation refers to the process of verifying and updating the credentials or qualifications of a professional or service provider on an as-needed basis. Instead of following a fixed schedule for revalidation, it allows revalidation to occur whenever necessary or requested.
In this case study, we will explore why On-Demand Revalidation offers a more effective solution for our needs. By delving into a real-life project as an example, we aim to provide a clear understanding of its advantages.
Project Description
The project is several online stores combined under a particular brand.
- For the backend, we used Ruby on Rails (6.1.4) + Spree (4.4.0).
- For the front, we used Next.js + Next.js Commerce (v1).
The application architecture is built to have one instance for the backend and many front-end applications (different stores). Currently, the number of front-end applications with a standard backend varies from 10 to 20, depending on the store’s brand.
What problem we encountered with Next.js
During the initial stages of development and before release, only a few products were in the stores, and the backend faced minimal issues with high load. However, as the project evolved and the stores became stocked with more products, we observed a significant increase in backend load, which remained elevated without user activity.
After a careful study of the load sources, we concluded that it’s all due to one of Next.js’s features, Incremental Static Regeneration for static pages. Let’s look at what it is and what it’s for.
Product pages are static pages rendered on the frontend server and stored in its cache. During the build, the front end requests information about each product and generates its own pages for the products. However, to keep product data up-to-date, it is necessary to revalidate it at regular intervals (in our case, 200 seconds). Thus, if the number of products in the store is small, the backend copes with this without problems. But if we have ten stores, and each store contains 1 million items, it means that every 200 seconds, all ten stores need to revalidate data about products:
(10 stores) x (1 million items) = 10 million requests every 200 seconds.
Serious enough load, even without taking into account the load from users.
Two typical Next.js functions that are responsible for ISR:
How we handled this problem
To eliminate the constant revalidation of product pages, we decided to switch to On-Demand Revalidation. It is a feature of Next.js that allows you to revalidate specific pages only when needed. It is achieved by creating a unique endpoint on the Next.js server that initiates revalidation. This way, you can eliminate millions of unnecessary requests, and pages will be updated only if there are some changes in particular products.
This way, we had to change the getStaticProps() function, add an endpoint on the front end, and add some extra logic to the back end. Specifically, we added callbacks when goods are updated, which will send a request to the front end that this product be revalidated.
In getStaticProps(), we removed revalidate:
We also added an endpoint to the frontend:
Added a callback on the backend for products:
And here’s an actual process of sending a request for revalidation:
Conclusion
So here’s what we’ve got in the end:
- Frontend applications stopped sending millions of requests to update their data, and the extra workload disappeared.
- Data consistency remained at the same level; any product change on the backend instantly updated the static page for that product on the frontend.
Read more about how we overcome technical challenges here.