serverless-nextjs / serverless-next.js

⚡ Deploy your Next.js apps on AWS Lambda@Edge via Serverless Components
MIT License
4.43k stars 451 forks source link

Question: Why reimplement Next.js? #2385

Open forresthopkinsa opened 2 years ago

forresthopkinsa commented 2 years ago

The README explains that this project suffers a lot of overhead due to reimplementing and maintaining feature parity with Next.js:

Since Next.js 8.0, serverless mode was introduced which provides a new low level API which projects like this can use to deploy onto different cloud providers. However, Next.js doesn't provide the full serverless routing logic, hence why this project is needed to fill the gap.

As we are emulating Next.js routing logic nearly from scratch to optimize it for a serverless environment, there may be some incomplete or missing features

However, it doesn't explain why this is necessary, which is pretty important when weighing the utility of relying on this library.

What exactly is the "full serverless routing logic"? Could a technical explanation for this be added to the README or Wiki or something?

jonahallibone commented 2 years ago

Next.js only outputs the files required to run the application, and at this point, it's meant to be agnostic of deployment target. Whether it be docker, raw node, or Serverless, the outputs should work. The piece it doesn't give you is infrastructure. Just because the code can run in lambdas doesn't mean it's giving you the infrastructure to run it. This package essentially emulates what Vercel does as a PaaS, in tying the pieces together and making them work. Think of server code vs static files vs network logic, etc, and then it becomes clear why this package needs to exist in order to run the code in a severless env on AWS.

forresthopkinsa commented 2 years ago

Thank you for responding! That clears up a lot of my confusion.

As an extension of my original question: why is this approach (serverless mode, one page per lambda) better than using standard Next.js with Lambda/APIGW proxy integration? Is it just to prevent long cold starts for really heavy applications?

agnese-kerubina commented 2 years ago

First to clarify. This repo does not do one (SSR) page per lambda - instead all SSR needed deps reside within a single lambda. I think that's one of the big differences between this deployment setup and Vercel's (don't take my word for it, I have not used Vercel).

Main difference between lambda@edge and regular lambda + api gatway is that lambda+gateway are regional services, while lambda@edge same as CloudFront "live" on edge locations, meaning a bit less latency . But both kinds of lambdas still have coldstarts. As a bonus lambda@edge is meant to play well with CloudFront thus that makes it a better choice for solving this problem (Edit: Ah and better is probably not even the right word. Theres always tradeoffs. There is some things lambda@edge are more limited than regular lambdas, like max size, but in return some things regular lambdas can't do.).

forresthopkinsa commented 2 years ago

Oh, okay, so it already is doing one big lambda. I guess that's another step closer to Proxy Integration.

It sounds like the point of this project, as opposed to Lambda/APIGW Proxy, is to run on Lambda@Edge – but that just adds to my confusion, because I'm specifically looking at using @sls-next/lambda. I'm totally uninterested in Lambda@Edge; the indev Lambda/APIGW library looks very promising to me but I'm just struggling to understand what problem it solves.

agnese-kerubina commented 2 years ago

AFAIK its a work in progress, as is making this project more platform agnostic, which is pretty cool.

Currently yeah, this project fundamentally runs on Lambda@Edge, need something in place of a server.

forresthopkinsa commented 2 years ago

I've learned some useful things in this thread, but unfortunately I don't think I'm much closer to an answer about [not] just using standard Next.js with APIGW proxy integration

jonahallibone commented 2 years ago

I've learned some useful things in this thread, but unfortunately I don't think I'm much closer to an answer about [not] just using standard Next.js with APIGW proxy integration

What you say standard Next.js with APIGW proxy what are you referring to? Do you mean just like deploying your static files to S3/CF and running your server files in a lambada? You're going to start missing a lot of functionality offered by Next, like redirects, rewrites, the image component, ISR, server rendering support, custom headers, and a lot of other things this library has taken into account. Your solution would probably only support static pages and API routes. If that's all you need then go ahead, but if you want to use a more feature complete Next.js, you're going to want to use this component.

forresthopkinsa commented 2 years ago

I mean running the plain Next.js production server in a Lambda, which, by my understanding, should support redirects, rewrites, server rendering, custom headers, and even middleware. Images and ISR could be trivially hooked up with S3 and EFS. Unless I'm missing some crucial detail here?

jonahallibone commented 2 years ago

I'd be curious to know if it works. From that description I'm inclined to think they won't (I'm speaking specially of ones used in next.config.js)

Also based on the issues in this repo/at netlify with ISR I'm thinking it's not as trivial as it appears, but again, I'd love to be wrong.

agnese-kerubina commented 2 years ago

I mean running the plain Next.js production server in a Lambda, which, by my understanding, should support redirects, rewrites, server rendering, custom headers, and even middleware. Images and ISR could be trivially hooked up with S3 and EFS. Unless I'm missing some crucial detail here?

You totally should be able to. That's another serverless alternative, where majority of features work out of the box. If you don't use next's provided server logic, and want a self managed serverless solution, you'll end up doing a couple of features by hand, hence this repo. Its just that next server is not really meant for serverless. Slapping next server on a lambda was the first thing I tried actually and I had very hard time managing size of the lambda (that was back then when 10th Next was still a thing). This repo however packs them deliciously small with added bonus of whole infrastructure configuration in a single file.

You probably already noticed yourself, but anything stateful is gonna require extra steps for them to work. The whole ordeal why ISR is not exactly cheesecake is that you might want to make sure that multiple users at the same time don't trigger revalidation build.

picosam commented 2 years ago

Thank you all for such an instructive thread! May I add a question: why not achieve the same Serverless aims using Fargate?

w0otness commented 2 years ago

Thank you all for such an instructive thread! May I add a question: why not achieve the same Serverless aims using Fargate?

Personally, because the projects I am working on are not frequently accessed, so the on-demand model of CF/L@E is more cost effective. Not sure at which scale Fargate would become better.