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 a technique 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 for revalidation to occur whenever it is necessary or requested.
In this case study we will explain why On-Demand Revalidation works better for us. We’ll use a real project as an example for a better understanding.
Project Description
The project itself is a number of online stores, combined under a particular brand.
- For the backend we used Ruby on Rails (6.1.4) + Spree (4.4.0).
- For the frontend we used Next.js + Next.js Commerce (v1).
Application architecture is built in such a way that we have one instance for backend, and many frontend applications (different stores). At the moment the number of frontend applications with a common backend varies from 10 to 20, depending on the brand of the store.
What problem we encountered with Next.js
In the process of development and before entering full production, there were few products in the stores, and the backend had almost no problems with the high load. But as the project developed and the stores were filled with products, we started to notice that the load on the backend increased significantly, and even without user activity it remained quite high.
After a careful study of the load sources, we came to the conclusion that it’s all due to one of the features of Next.js, namely Incremental Static Regeneration for static pages. Let’s look more closely at what it is and what it’s for.
Product pages are static pages that are rendered on the frontend server and stored in its cache. During the build, the frontend requests information about each product and generates its own pages for the products. But in order 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 10 stores, and each store contains 1 million items, it means that every 200 seconds all 10 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
In order to get rid of 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 special endpoint on Next.js server, that initiates revalidation. This way you can get rid of 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 frontend and add some extra logic to the backend, namely to add callbacks when goods are updated, which will send a request to the frontend that this product should 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 change of a product on the backend instantly updated the static page for that product on the frontend.
Read more about how we overcome technical challenges here.