Edge Runtime 不是 CDN 上的 Node.js:Next.js 16.3 起 runtime = 'edge' 已不再支持
Edge Runtime 是基于 V8 isolate 的独立运行时,不是把 Node.js 搬到 CDN 上。它没有容器、没有虚拟机、没有持久进程,写法和限制都跟跑在源站的 Node.js 不是一回事。
这到底是什么
Vercel 官方文档(https://vercel.com/docs/functions/runtimes/edge)的描述是:
- Edge Runtime 构建在 V8 引擎上,运行在隔离的执行环境里,不需要容器或虚拟机。
- 默认在离请求最近的区域执行,可以用路由段配置
preferredRegion,或 config 里的regions指定区域。 - 某个区域故障时,自动把流量转到最近的 CDN 区域(failover)。
Cloudflare Workers 那边是同一套底层思路:两者都跑 V8 isolates 而不是容器,单进程多租户,JS 引擎级隔离,冷启动接近 0ms(isolate 初始化 <1ms)。Cloudflare Workers 的运行时叫 workerd,开源,可以用 Wrangler 在本地跑起来。
支持和不支持的 API
Edge Runtime 提供的是一个 Web API 子集:fetch、Request、Response、Web Crypto、Streams、URL。
不支持的部分:
- 文件系统读写。
- 直接调用
require,要用import。 - 动态代码执行
eval因安全原因不可用,依赖eval的库会在运行时报错。 - 除上面列出的之外,多数 Node.js API 不可用。
node_modules 是能用的,前提是 ESM,并且不依赖原生 Node API。
workerd 暴露的 API 比 Vercel Edge 更全一些:带完整 backpressure 的 Streams、服务端 WebSocket(Durable Objects 可休眠)、Cache API、Worker 间 RPC 子请求、WebCrypto 含 key wrapping。Vercel Edge 用的是常用子集,长连接、实时、服务端推送方面受限更多。
硬限制对照表
| 项目 | Cloudflare Workers | Vercel Edge |
|---|---|---|
| 内存 | 128MB | 128MB |
| CPU 预算 | 免费 10ms;付费默认 30s,可配到 5 分钟(同步 CPU) | 无独立 CPU 预算 |
| 挂钟超时 | I/O wait 不计入 CPU,但计入挂钟 | Middleware 1000ms;函数 25s 首字节 / 300s 流式 |
| bundle | 免费 1MB / 付费 5MB 未压缩(gzip 后 3MB / 10MB,压缩前 64MB) | 1–4MB(取决于套餐);Edge Middleware 1MB 未压缩 |
状态原语方面,Cloudflare 有 KV、R2、Durable Objects、D1;Vercel 有 Edge Config、Vercel KV、Blob。
CPU 时间不等于挂钟时间
这两个不是一个东西,混淆了很容易把预算算错。
Cloudflare 的 CPU 预算指的是同步 CPU 时间:免费 10ms,付费默认 30s,可配到 5 分钟。出站 fetch、KV 读这类 I/O wait 不计入 CPU,但计入挂钟时间——等一个慢接口不会烧掉 CPU 预算,但请求本身会一直挂着。
Vercel Edge 没有独立的 CPU 预算这一说,卡的是挂钟:Edge Middleware 的挂钟超时是 1000ms,函数必须在 25 秒内开始发送响应以保持流式能力,之后最多可持续流式 300 秒。
边缘连数据库的延迟陷阱
Edge 不是完整的服务器环境,是另一套思维模型。
先看限制:没有原生模块,bcrypt、sharp、canvas 这类 C++ 绑定用不了;没有持久连接,isolate 是临时的,请求之间无法保持数据库连接,请求处理完可能被回收。
然后是延迟。你的数据库在一个区域,edge 在 300+ 区域。每次查询都要从 edge 节点跨到数据库所在区域再返回,上游数据库和 API 的延迟往往主导整体延迟——边缘就近执行省下来的那点时间,被这一跳吃掉了。
打包体积也卡得死:Cloudflare 1MB(免费)/ 5MB(付费),Vercel Edge 4MB(压缩后),Deno Deploy 20MB。
所以 Edge 适合的是在请求到达源站前做快速决策:守门人、路由器、转换器,不是应用服务器。把快的部分放这里——鉴权、重定向、A/B、本地化、feature flag;慢的部分——DB 查询、重活——留给源站。
Next.js 16.3 撤掉 runtime = 'edge'
Vercel 现在的建议是从 edge 迁移到 Node.js,理由是性能与可靠性提升,两者都跑在 Fluid compute + Active CPU 计费上。
关键变化:从 Next.js 16.3 开始,设置 runtime = 'edge' 不再被支持,路由和页面统一跑在 Node.js 上。
另外,Next.js middleware 始终跑在 edge——这是设计如此,它会拦截每一个匹配的请求。
其他平台的情况:Deno Deploy(V8 + 原生 Deno API,TypeScript 原生,20MB 包)、Fastly Compute@Edge(以 WASM 为基础,支持多语言)、Netlify Edge Functions(Deno 运行时)。
该用在哪儿
判断标准就一条:这段代码是不是在请求到达源站之前做决策。
适合:鉴权、重定向、A/B 分流、本地化、feature flag 读取。这些操作输入输出都小,不碰原生模块,一两次 fetch 或一次 KV / Edge Config 读取就能结束。
不适合:需要数据库连接池的查询、图像处理、PDF 生成、加密哈希(bcrypt 这类)、任何依赖 eval 的库、任何需要长连接或服务端推送的场景。
怎么判断当前在不在 edge
检查全局属性 globalThis.EdgeRuntime:
if (typeof globalThis.EdgeRuntime !== 'undefined') {
// 运行在 Edge Runtime
}
这个判断在需要给同一份代码写两条分支时有用——比如在 edge 里走 fetch 调外部服务,在 Node.js 里直接查库。