本文同时参与两场活动:
1)「玩透 ESA」征文:https://event.alibabacloud-esa.com/
2)「发帖送 ESA」免费领取活动(需带官方链接):http://s.tb.cn/e6.0Fu67m
我的项目场景
- 技术栈:Next.js 14(App Router)、SSG + ISR、Tailwind CSS。
- 业务形态:知识付费小站,月 PV 9 万,带宽 45GB / 月。
- 访问分布:国内 72%,港澳台 10%,北美 / 欧洲 18%。
- 多媒体:每篇文章 6-10 张 WebP 配图,单图 200-400KB。
去年把前端放在 Cloudflare Pages,配合 Cloudflare Images 做裁剪和 WebP 输出,海外体验不错。但国内用户一直反馈 “首屏空白 2-3 秒”,最近双十一 PV 突增,问题更明显。预算为 0,只能优先折腾成本最低的方案。
为什么最初用 Cloudflare Pages
-
免服务器 + 自动 SSL
接 GitHub,一键构建,Pages + Images 打包提供 HTTPS、缓存、基础防护,几乎零运维。 -
Workers 边缘函数
我用 Workers 做 A/B Test 和灰度,写法跟 Cloudflare 平台绑定,体验确实顺滑。 -
海外性能很强
在旧金山 / 法兰克福测 TTFB 都在 40-60ms,图片裁剪也很稳。
问题暴露:国内延迟和图片回源
1. 国内 TTFB 不稳定
10 月用站长工具全站测速(平均值):
- 北京:TTFB 430ms
- 上海:TTFB 480ms
- 杭州:TTFB 410ms
- 广州:TTFB 470ms
- 成都:TTFB 520ms
高峰期甚至飙到 700-900ms。原因大家懂:Cloudflare Pages 主节点在海外,国内没有边缘落地。
2. 图片偶发 522/523
Cloudflare Images 在香港节点回源,偶尔打满,日志里一天能看到 30-50 次 522/523,导致页面出现断图或等待 1-2 秒才恢复。
3. 成本不算低
- Pages 免费,但 Images 按量计费 + 存储,月均 28 美元。
- Workers KV 做 ISR 缓存控制又是单独计费。
流量一涨就开始心疼。
选择 ESA 的理由(站在个人开发者角度)
-
国内节点 + ICP 备案域名
我的域名本来就在阿里云备案,ESA 能直接走国内边缘节点,理论上 TTFB 可以压到 20ms 以内。 -
边缘计算兼容 Node Runtime
Next.js Middleware 可以直接跑在 ESA Edge Functions,上下文和 Node API 兼容度够用。 -
内置图片处理(图像缩放 + WebP/AVIF)
避免再接第三方图片服务,减少 522/523 风险。 -
能 “白嫖” 起步
我用的是 ESA 基础版 + 活动送的 50GB 流量包,目前 0 付费运行。超量单价也比我之前的 Images 便宜一些,但核心是先不花钱。
迁移步骤(实操记录)
第 1 步:打包构建产物
在 CI 里保持原来的 next build,输出 .next。为了让 ESA Edge Functions 处理 SSR/ISR,需要导出 Server Bundle:
NEXT_TELEMETRY_DISABLED=1 \
NEXT_PRIVATE_STANDALONE=true \
next build
生成的 standalone/ 目录直接上传到 ESA。
第 2 步:配置 ESA Edge Functions
- 运行时选 Node.js 18,超时 3s。
- 入口文件:
standalone/server.js。 - 环境变量:
NODE_OPTIONS=--enable-source-maps,方便排错。
第 3 步:静态资源分层缓存
/static/*、/_next/static/*缓存 30 天,cache-control: public, immutable.- 页面级:
/、/post/*设置s-maxage=300, stale-while-revalidate=86400,让 ISR 命中边缘缓存。
第 4 步:开启 ESA 图片处理
- 上传原图到 OSS,ESA 开启 “边缘图片处理”,规则:
?x-oss-process=image/resize,w_1280/format,webp/quality,Q_75- 移动端判断 UA,小于 768px 输出
w_720。
- 页面里统一调用:
const src = `${cdn}/images/${key}?x-oss-process=image/resize,w_${isMobile?720:1280}/format,webp/quality,Q_75`;
第 5 步:灰度与 A/B Test 迁移
- 把原先 Workers 中的 AB 逻辑改成 ESA 边缘函数中间件,使用 Cookie 划分(逻辑保持最小改动):
export default async function handler(req, res) {
const group = req.cookies.ab || (Math.random() > 0.5 ? 'A' : 'B');
res.setHeader('Set-Cookie', `ab=${group}; Path=/; Max-Age=2592000; Secure; HttpOnly`);
// 根据 group 分支到不同渲染路径
}
第 6 步:全链路监控
- 前端埋点:TTFB、FCP、LCP、CLS、Error。
- ESA 控制台打开访问日志 + 边缘函数日志,便于对比。
性能对比数据
12 月 1 日晚高峰(19:00-22:00)对比,取 5 地各 30 次样本(自测,样本量有限,仅供参考):
| 城市 | Pages TTFB (ms) | ESA TTFB (ms) | 首屏时间 FCP (s) |
|---|---|---|---|
| 北京 | 450 | 18 | 0.9 |
| 上海 | 470 | 19 | 0.9 |
| 广州 | 430 | 21 | 1.0 |
| 成都 | 520 | 25 | 1.1 |
| 深圳 | 480 | 18 | 0.9 |
- TTFB 平均从 470ms 降到 20.2ms。
- 首屏 FCP 从 2.6s 降到 0.96s,跳出率一周内从 39% 降到 24%(数据来自站内埋点)。
- 图片错误率从每天 30+ 次 522/523 降到 0(统计 7 天)。

成本和白嫖状态
- Cloudflare 阶段:Pages 免费,但 Images + KV + 日志约 28 美元 / 月。
- 迁到 ESA:目前用活动送的 50GB 流量包 + 基础版试用,实际扣费为 0。如果后续超量,按官方单价估算大概每月 < 20 美元,对我这个体量可以接受。
遇到的小坑与解决
- Next.js 动态路由 rewrite:需要在 ESA 配置里显式把
/post/*指向边缘函数,否则会被当作静态文件 404。 - ISR 缓存同步:初次渲染后的 revalidate 可能在少数节点不一致,在 ESA 后台打开 “回源一致性” 后,缓存刷新变得稳定。
- 源站 301:把原 Cloudflare 域名做 301 指向 ESA CDN 域名,否则部分用户的老书签会命中旧节点。
迁移总结(主观感受)
- 如果主要流量在国内,Cloudflare Pages/Images 的海外优势难以兑现,延迟就是硬伤。
- ESA 的国内节点 + 图片处理 + 边缘函数,让我基本不改业务代码就把延迟拉下来了。
- 成本方面,现阶段靠活动流量包白嫖,后续超量再看;至少对个人站 / 小流量站是个可行的低成本选项。
接下来我计划:
- 在 ESA 上打开 WAF 规则,观察误杀率。
- 引入
stale-if-error,提升发布时的容错。 - 继续写一篇 “ESA + Server Actions” 的小实验(顺便交征文任务)。