AWS
常见问题

我的 Next.js 应用表现会与在 Vercel 上一样吗?

OpenNext 旨在使用 CloudFront、S3 和 Lambda 等服务将您的 Next.js 应用部署到 AWS。虽然 Vercel 也使用一些 AWS 服务,但它还拥有专有基础设施,导致功能对等性上存在自然差距。而 OpenNext 正在填补这一差距。

一个架构差异在于 中间件 (opens in a new tab) 的运行方式,但这不应影响大多数应用的行为。

在 Vercel 上,Next.js 应用使用未文档化的 "minimalMode (opens in a new tab)" 方式进行构建。中间件代码与服务器代码分离并部署到边缘位置,而服务器代码部署到单个区域。当用户发出请求时,中间件代码首先运行。然后请求到达 CDN。如果请求被缓存,则返回缓存的响应;否则,请求会命中服务器函数。这意味着即使是缓存的请求也会调用中间件。

另一方面,OpenNext 使用标准的 next build 命令,生成一个包含中间件代码的服务器函数。这意味着对于缓存的请求,CDN (CloudFront) 将返回缓存的响应,并且不会运行中间件代码。

我们之前使用 "minimalMode" 构建应用,并采用与 Vercel 相同的架构,其中中间件代码将在 Lambda@Edge 的 Viewer Request 上运行。请参阅 vercel-mode 分支 (opens in a new tab)。然而,我们出于以下几个原因决定该架构不适合 AWS:

  1. 冷启动 - 在两个独立的 Lambda 函数中运行中间件和服务器会导致延迟加倍。
  2. 维护 - 由于 "minimalMode" 没有文档,可能会出现未处理的边缘情况,并且排查需要不断逆向工程 Vercel 的代码库。
  3. 功能对等性 - 在 Viewer Request 上触发的 Lambda@Edge 函数无法访问地理位置标头,这会影响 i18n 支持。

OpenNext 与 AWS Amplify 相比如何?

OpenNext 是一个开源项目,与 Amplify 相比有几个优势:

  1. 社区对 OpenNext 的贡献使其拥有更好的功能支持。例如,Amplify 目前不支持 按需重新验证 (opens in a new tab)

  2. Amplify 的 Next.js 托管是一个黑盒。资源不会部署到您的 AWS 账户。所有 Amplify 用户共享 Amplify 团队拥有的同一个 CloudFront CDN。这阻止您自定义设置,并且如果您正在寻找类似 Vercel 的功能,自定义很重要。

  3. Amplify 的实现是闭源的。Bug 修复通常需要更长时间,因为您必须通过 AWS 支持。并且在除 Vercel 以外的任何地方托管 Next.js 时,您可能会遇到更多怪癖。