-
-
Notifications
You must be signed in to change notification settings - Fork 456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC - Static Generation / SSG Improvements #355
Comments
So in step 2, if not cached in cloudfront yet, it would always call the lambda and not S3 directy, right? How would the static fallback page be returned in that step, while the actual page is still rendered? Also: Could it be possible to avoid calling the lamba, and just utilize that logic directly in cloudfront somehow, maybe by defining behaviours per page? So that Cloudfront could directly make calls to S3, and if a page is not present, serve the fallback page for that route, and still trigger that lambda for the page creation. Or if triggering the lamba is not possible, still do the initial lookup from S3, and if not present, call the lambda and make that serve the static fallback page while still creating the actual page. Or do the opposite, and serve the static fallback page from S3 and make that page trigger the lambda in its client side while it's in fallback mode and awaiting the page. Although the overhead might be negligible as most things will be cached in Cloudfront, I was under the impression that the architecture would allow to always serve any request for a static page directly from file, without needing to call a function first, including the fallback and revalidate pages. |
Hi @janus-reith Thanks for the questions! Made me realise a few things I didn't consider before. Let me start with this:
It is possible but wouldn't scale. CloudFront has a limit of 25 cache behaviours per distribution. It wouldn't work for apps with more than 25 page routes which is a fairly common use case.
Yes you are correct, it would call the lambda. Also, this question made me realise something I had missed. I assumed by setting I'll keep looking for solutions, any ideas are appreciated 🙏 |
Thanks for the explanation, I didn't know about that Cloudfront limit.
Could my third suggestion work for this maybe? One could probably verify easily if default |
@janus-reith I may have a come up with a solution similar to what you suggested. Let me know what you think 🙏 A few notes on this approach:
cc. @oseibonsu |
@danielcondemarin Im not sure about that last part where you get /blog/hello, it seems redundant if you already fetched the json. |
That last part is just to illustrate what would happen if there is a second request after the actual page and JSON props file has been generated in step 2. |
Ah ok, yes I agree then, it wasn't clear for me in in the diagram - Maybe separate that third step from the other two which are connected? :) |
I've updated the RFC with an updated diagram that provides description for each step so is more clear 👍 |
Afaik Next.js relies heavily on RFC5861 for serving stale content and revalidating pages in the background. Currently this extension is not supported by Cloudfront. Nevertheless it definetly would make sense to follow the RFC as close as possible. |
@HaNdTriX I guess this would make it possible to skip the lamba and serve directly from S3 instead if available? |
@HaNdTriX I will be covering vercel/next.js#11552 on a separate RFC. Whilst CloudFront doesn't support |
Hi folks, I've just merged to master support for Thanks to @mertyildiran for doing all the hard work! |
Hey @danielcondemarin I could test it in a couple of projects, is this pushed into an alpha release on npm? Or should I just pull from github |
Thanks a lot @Negan1911 . I'll get it deployed to an alpha release today! |
@danielcondemarin Are you free for a quick chat about this, please find my LI here: https://www.linkedin.com/in/marc-fielding-a8bb3293/ I mentioned you guys in GCS connect talk I was doing yesterday, I really, really want us to commit to using this since it'll change the way we do eCommerce. FYI We can test this across almost 600 pages that require these features. |
@Negan1911 and anyone else who can test I've now published |
@danielcondemarin Only have to say something: Works incredibly good, seriously! I'm on the early steps of building my own startup with a cofounder, and our UI deployments are based on this library, as soon as we get a better budget that doesn't depend on my monthly salary I would definitively come back and donate. Thanks for maintaining this library! |
@danielcondemarin tested both |
n/m, I wasn't link to dynamic routes correctly :( That part works perfectly. |
@Negan1911 Heh us two, I don't think I've been this excited about something since the first release of Doom. |
@danielcondemarin when will you merge [email protected] !! |
Works well for us with However navigating to a page using |
Nope. Only the
No objections, it simplifies things. We can document which version of next is required for it to work.
That one will be tricky to implement. We could discuss it separately after this RFC is completed. |
Hello @lone-cloud and @danielcondemarin! I would like to offer my support to this repo and help contribute to its code base. Wasn't sure what the best way was to contact you both so please forgive me if this wasn't the proper avenue. I've read the contribute readme and I'm fully setup and ready to go. Let me know what I could tackle, or help tackle. Thanks, Andrew |
@andrewgadziksonos Appreciate the help, thanks! Could you send me a DM on twitter and I'll add you to our contributors channel. |
@danielcondemarin It says you can't be messaged directly. Here's my twitter |
I am testing this out and noticed that the |
@danielcondemarin is there progress on supporting the
|
I've not had time to look into the
Pre-rendered dynamic routes should work fine. Are you seeing any issues?
To check if there is a fallback page from the origin-request handler you'd need a roundtrip to S3 as the lambda function doesn't have any fallback HTML pages in the deployment artefact. The flow I proposed is not much different, only that it does the roundtrip on
If is a client side transition to a SSR page (aka |
@danielcondemarin thanks for the feedback - I am working on this. |
Props to @thchia for adding |
@danielcondemarin I am thinking about Preview Mode (not sure I can commit to working on it yet). I believe that preview mode is indicated by the presence of certain cookies, meaning that in order to make sure we don't accidentally cache the preview response, we should be:
Edit: As I am playing around, having not done either of these things, the problems I expected are not appearing. I'll keep looking at it. Edit 2: The cache behaviour for |
@danielcondemarin I am thinking about Preview Mode (not sure I can commit to working on it yet).
That's right. More specifically there are 2 cookies involved,
I think the first one is simply to indicate the page should be SSR'ed instead of it being pre-rendered and cached at the edge locations. The second cookie is used to validate the preview request was issued from someone with access to preview mode.
👍 |
I hope unstable_revalidate will be supported soon. |
Hi folks, I've published |
I assume nobody looked yet at |
@danielcondemarin @dphang - do you have any update regarding implentation of |
Implementing |
@danielcondemarin not too familiar with the internals, would something like this make sense (very simplified):
This essentially moves the background regeneration into a separate lambda. |
@faceshape That's a sensible idea I've actually mulled over before. However it has a few downsides, one is it requires another piece of infrastructure (SQS) to add. While it may not seem like a big deal, the more infrastructure surface we add to serverless-next.js, the slower builds get and more difficult it is to maintain the project. The second, strictly speaking even making a call to SQS to post a message, would be blocking, as in, we have to wait for the request to SQS to fulfil before returning the response to the client. |
I wonder what I'm missing here - A separate lambda invocation makes sense, but why would SQS, or anything else on top be necessary? Couldn't the first Lambda just invoke the second lambda with |
You're right @janus-reith. That removes the need for SQS even though I think AWS still uses a queue behind the scenes for async invocations, but if is abstracting it away from us that's best! My only remaining concern would be latency between regions, say that a user is in us-east-1 and hits one of the edge functions in that region, when invoking the other lambda for background page regeneration what latency are we expected to see? I realise that it won't need to wait for the regeneration lambda to process but the request itself to put the event in the queue what region is that happening and how do we know is not going to a queue somewhere in |
Since all of the features in the RFC have now been implemented will close this and we can open a separate issue for |
Problem
Next.js recently released a new API designed to improve Static Site Generation. More details can be found in vercel/next.js#9524.
serverless-next.js
is not currently compatible with the new Next.js API and this RFC proposes changes to support these features.Proposal
getStaticProps
.For pages that declares
getStaticProps
, Next.js generates a JSON file that holds the return value of executinggetStaticProps
. The file is used for client-side routing.All JSON files for a given build can be found in
.next/prerender-manifest.json
.serverless-next.js
will lookup the files and upload them to S3 so they can be fetch-ed from the browser.Also, a new cache behaviour will be created in CloudFront for the path pattern
/_next/data/*
. This will match any requests made to the JSON files and forward them to S3.getStaticPaths
When you have a dynamic route you can add a method called
getStaticPaths
to the page. The way it works is Next.js generates afallback
HTML page that can be served when the route has not been pre-rendered on a previous request.If the path is returned in
getStaticPaths
then is pre-rendered at build time. If is not pre-rendered at build time then it needs to be compiled server side in the background the first time the route is visited.Here is a diagram to illustrate how this will work in
serverless-next.js
(fallback: true
):You can also set
fallback: false
. In this case a 404 is returned instead of pre-rendering:getServerProps
getServerProps
behaves similarly togetInitialProps
. The difference is that on client side transitions, Next.js makes an api request to the server to rungetServerProps
and uses that to render the page client side.In
serverless-next.js
this will be handled in theorigin-request
edge function as illustrated below:Preview mode
Preview mode enables you to preview the "draft" of a page at request time rather than build time. Next.js achieves this by always calling
getStaticProps
on the page at request time whenever preview mode is enabled. Details of how to enable preview mode and use it can be found in https://nextjs.org/docs/advanced-features/preview-mode.In
serverless-next.js
this will be handled in theorigin-request
edge function as illustrated below:The text was updated successfully, but these errors were encountered: