Nextjs和Vercel的几种踩坑知识点
AI摘要: 本文深入探讨了Next.js在Vercel平台上的部署与优化,详细解析了SSR、ISR、SSG三种渲染方式及其实现机制,对比分析了cache()与fetch()在不同场景下的应用差异,并针对Serverless环境中的数据库使用挑战提出了解决方案。
背景
在Vercel上部署项目时候,一直以来总会遇到偶尔的报错,但是没有在意。此外,没有深入理解
serverless和普通部署的区别,以及Next.js的一些针对serverless的优化。
Next.js的几种渲染方式
-
SSR:完全的服务端渲染,来一次请求,启动一个实例,访问一次数据库,拿到一次数据,渲染一次页面,适合实时性非常强的情况。
-
ISR:这个其实是静态的,放在CDN上,但是会定期重新渲染,然后再投放到CDN上,所以本质是静态的,不涉及服务端的,适合实时性不那么强的情况,速度又要求优先,比如博客。
-
SSG:这个最好理解,完全的静态,丢到CDN上。
Next.js如何实现这些方式:
-
SSR: getServerSideProps
-
ISR: getStaticProps,可以增加了一个revalidate参数,表示重新编译,周期性地投放到CDN
-
SSG: getStaticProps,不带revalidate参数,完全静态,所以除非重新编译,否则永远不变
关于 cache()
和 fetch()
的理解
在 Next.js 中,应从「实例级别」的运行机制(特别是在 Serverless 场景下)出发去理解。
cache()
-
缓存作用域限制在单个 Node.js 实例中
cache()
是对函数执行结果的缓存,仅在当前的 Next.js 实例中有效。也就是说,如果你在一个实例中多次调用该函数,结果会被缓存,避免重复计算。但需要注意的是:
-
在多实例部署(如 Serverless 或 Vercel)中,每个实例之间的内存不共享,因此缓存是隔离的;
-
一旦实例销毁(例如 Vercel 的 Serverless 冷启动),缓存也随之丢失。
-
-
与 ISR 配合时的表现
cache()
可用于 ISR 的构建阶段,用来缓存某些重复执行的函数,提升构建效率。构建完成后,静态页面会被上传到 CDN,后续请求直接命中 CDN,根本不会再执行这些函数或触发cache()
。 -
与 SSR 配合时的作用
在 SSR 场景下,
cache()
可以减少页面渲染期间的函数重复调用,提高服务端响应效率。但它不能跨请求共享缓存,也不具备增量更新的能力,无法替代 ISR。更重要的是,在 Serverless 环境中,由于实例生命周期短且无状态,
cache()
缓存无法持久,几乎没有实际意义。
Serverless 环境的 SSR 隐患
在 Serverless 架构下(如 Vercel 的默认部署方式):
-
每个请求可能对应一个全新实例(cold start);
-
数据库连接池等长生命周期资源无法复用;
-
多次快速刷新页面可能引发数据库连接频繁创建、耗尽资源甚至崩溃。
因此,如果要使用 SSR 且依赖数据库,建议:
-
使用 Prisma Data Proxy 或 PgBouncer 等连接池代理;
-
避免 SSR 频繁访问数据库,优先使用静态生成或缓存机制。
Serverless 如何使用数据库
在 Serverless 架构中,如果需要持久化云端数据,常见处理方式如下:
-
小项目:使用 Upstash Redis(支持 HTTP 请求,天然适配 Serverless)
-
大项目:使用 Supabase 或 Prisma + 数据库连接池代理(如 PgBouncer)
传统数据库使用 TCP 长连接并依赖连接池,在 Serverless 中因函数无状态、短生命周期,连接池难以复用,容易导致连接数耗尽。Supabase 通过 PostgREST + PgBouncer 优化了连接复用,但这并不能完全解决问题。
好处是,中间件可以减少每次连接时的鉴权、事务初始化等开销;但本质上连接压力只是从数据库转移到了云函数和连接池代理之间,这个部分仍然是短连接,无法避免。
export const dynamic = "force-static";
值得注意的是,我平时之前不太喜欢用fetch来获取数据,而是采用函数包装prisma,但是这种方式,nextjs是无法识别为ISR的,fetch倒是可以,如果一定要通过prisma也是先ISR,可以手动加上export const dynamic= "force-static";来告诉nextjs,这个是静态页面,然后再加上export const revalidation = 3600实现ISR
才疏学浅,没有深入研究过serverless,根据偶尔白嫖vercel总结的知识点。