RFC: Incremental Static Regeneration #11552
Replies: 85 comments 368 replies
-
So excited for the future! |
Beta Was this translation helpful? Give feedback.
-
You would still need a full rebuild if you change something shared with all pages eg header, correct? |
Beta Was this translation helpful? Give feedback.
-
This looks awesome, a great proposal 🚀 As you stated on the upsides:
|
Beta Was this translation helpful? Give feedback.
-
Great to see another RFC in this area. A few specific points of feedback: 1: It took me a while to realize that this would happen on the server (or a serverless platform like Now) at runtime. The word static is commonly associated with a build-time process, producing something that can be uploaded to a "dumb" CDN. I sort of realize now that you're talking about the end user experience – they would always get a static HTML – but this RFC basically proposes a behavior that's similar to SSR + nginx microcache (please correct me if I'm wrong) and that's not commonly referred to as SSG. 2: With these micro-caching strategies, it's often problematic to set the "right" timeout. In fact, there often isn't any one value. That's why most CMS's don't send aggressive You could argue that if you know your site, you can set this number sensibly but in my experience, it's always a tough choice. 3: In the RFC, it might be worth pointing out what this background re-rendering means for the backend uptime guarantees. With SSG, I can turn the headless CMS off after I've generated the site; here, I don't. I assume that if the response from the backend is an error, the previously rendered HTML is still returned. This could also lead to situations where |
Beta Was this translation helpful? Give feedback.
-
First up, I really like this RFC. You folk already had me interested with getStaticProps and getStaticPaths, but this is next-level exciting! 🎉 My initial response:
|
Beta Was this translation helpful? Give feedback.
-
Great proposal, thanks for this! I'd love to see an API for event-driven changes. @Timer already mentioned it's on your plans, so I'll just share my current use case and why it would be helpful. Currently, I'm using Next.js with a Firebase backend to build a collaborative platform for learning where users can edit any page (similar to how Wikipedia works). This means a page can change multiple times a day. This RFC would allow me to use However, I could save lots of money if we'd have an event-driven API because I could create a Firebase Cloud Function for listening to post changes, for example, and send a request to update that post's page only. Anyway, I'm glad to see the direction you're going. I've been working with Next.js for less than a year but it has been a great experience so far. Thanks for your hard work! |
Beta Was this translation helpful? Give feedback.
-
I have this feature today. We run nextjs in a docker container in Fargate. We have a CDN that fronts all of that. Each request hits our CDN, then our origin (Nextjs). If the page exists in the CDN, the origin doesn't get hit, bit it doesn't then nextjs serves the response. When "our database updates", we just proc a cdn cache invalidation to that changed route, and depended routes for that matter. The only thing I see this new pattern solve, is being able to de-bounce failed responses, with previous successful responses. We serve close to 300k distinct pages out of nextjs, if we flick on SSG - would we need disk space to house all of those html docs? |
Beta Was this translation helpful? Give feedback.
-
Great proposal! I have a question. In our e-commerce we are using SSR returning different content depending on the delivery country (stored on a cookie), but the page route can be the same (bots always see the default delivery country because they don't change the country). Is there any plan to support this? Or the only way is to add an extra slug with the delivery country...? |
Beta Was this translation helpful? Give feedback.
-
How would this work if the site assets are built with a CDN prefix; in addition to having multiple copies of the same container/build running in a ECS cluster, around 200 of them at the same time? |
Beta Was this translation helpful? Give feedback.
-
Awesome proposal and I love how fast you are moving forward with static generation options. Combined with the We're running republik.ch, an Swiss German online magazine, on next.js starting with v2 and running v9.3.4 right now. Currently we're still 100% server-side rendering—using apollo in While a bit off topic, here is what currently is still blocking me:
I considered abusing preview mode for the «signed in» segment but that felt wrong. Maybe preview mode could be made more flexible—allowing a custom function to determine whether to live render or not. For us live rendering for signed in users would be an option because we've already build an html partial caching solution. The non-plus-ultra solution for us, and maybe other hybrid users, would be to have a custom segmenting function that determines which cache and caching strategy should be used for a request. Maybe this function could also solve the 404 case: use live mode if not part of the current static path list. |
Beta Was this translation helpful? Give feedback.
-
One of the big feature of a SSG website is the ability to put it on a CDN: incremental build for me is like a partial CDN purge and about it for my static contents I'm using Fastly and its Surrogate Keys feature: you can tag a content with one or many tags as you want and then purge it by tag and not a full purge of the cached contents. In this direction I think rebuild in background only the pages tagged by a key could be the right approach (calling an API with one or more keys). |
Beta Was this translation helpful? Give feedback.
-
If you have a cluster of many NextJS instances running at the same time, and node1 receives a request and regenerates a static page, wouldn't node2 (not hit by any request currently) be out of sync? I guess it could be mitigated by having a caching layer on top, and ensuring that if node1 revalidates, then the cache will not hit node2 before the new node1 static content expires. (just thinking out loud) Note:
|
Beta Was this translation helpful? Give feedback.
-
This is a good start imho to make static sites more accessible. However it would be ideal to be able to send some kind of trigger to the server with a flag or something in those lines that a page needs to be rebuild. isn't it a waste of resources if you'd work with only the timeout option? (not sure how much it uses) |
Beta Was this translation helpful? Give feedback.
-
Is this available with v9.3? Or is it at the proposal stage? |
Beta Was this translation helpful? Give feedback.
-
Update: This has been released. See the docs for more information. The RFC will remain for historical context.
Summary
Fully automatic re-rendering of statically exported pages without a full rebuild.
With regards to static site generators this feature has been referred to in multiple ways, most commonly "Incremental builds" or "Incremental rebuilds".
This RFC exclusively discusses API additions. All new functionality is completely backwards compatible and can be incrementally adopted. This RFC introduces no deprecations.
Background
Next.js recently introduced support for next-gen Static Generation (SSG) in v9.3.
Generating static pages in Next.js using
getStaticProps
andgetStaticPaths
provides numerous upsides:However static generation as it exists today has one downside that makes it hard to adopt for larger websites or applications:
Every time something changes in the database a full rebuild is required in order to see the change in one single page.
An example to illustrate this is when you make a change to a blogpost in a headless CMS, you could be only updating the title of one blog item. After you make the change the application would require a full rebuild of all pages, just to make that one change visible.
In order to make static sites scale we have to regenerate pages without needing a full build of the application.
What if we could generate a new version of the page on-demand when a new request comes in, but without having the user wait for the re-rendering?
Effectively re-rendering the page in the background while the previous version of the page keeps being served.
The background re-rendering could be triggered based on a timeout, similar to the way that
Cache-Control
'smaxage
works, when the timeout is exceeded a background re-render is triggered when a request comes in.This would look something like:
This model is pretty ideal for static generation:
This allows for true incremental rendering of static pages in Next.js.
After this RFC for incremental static generation is implemented we can extend it to do force revalidation, which would be useful for CMS providers that want to get the content updated as quickly as possible.
Implementation
Next.js 9.3 introduced
getStaticProps
, ingetStaticProps
you'll be able to return arevalidate
property in order to opt-in to automatically generating in the background when a request comes in:Keep in mind that the timeout defined is a timeout for when an incoming request will re-render in the background. Meaning that the first request after the timeout period will serve the previously rendered page and then the page is regenerated in the background.
When you opt-in to
revalidate
you get:Co-authored with @rauchg @Timer
Special thanks to @juancampa @dav-is
Beta Was this translation helpful? Give feedback.
All reactions