边缘计算不只是把服务器换了个地方:我拿 Cloudflare Workers 把首屏时间从 2.3s 降到了 0.8s

边缘计算不只是把服务器换了个地方:我拿 Cloudflare Workers 把首屏时间从 2.3s 降到了 0.8s

你是不是也这样:项目做完了性能优化,CDN 也上了,图片也压缩了,结果一测首屏还是 2 秒多。用户在欧洲,国内服务器延迟 300ms 起步,怎么优化都救不回来。

我去年就遇到了这个情况,后来把一部分逻辑搬到了边缘节点,首屏直接从 2.3s 掉到了 0.8s。不是玄学,是真的把服务器”搬到了用户家门口”。


边缘计算到底是什么

简单说,边缘计算就是把你的代码跑到离用户最近的服务器上。不是北京机房,是法兰克福、洛杉矶、东京——用户的物理距离可能只隔了几十公里。

传统架构:用户请求 → 国内服务器(假设在浙江)→ 数据库/业务逻辑 → 返回。用户在欧洲?单程延迟 300ms,加上处理时间,2~3 秒很正常。

边缘架构:用户请求 → 最近的边缘节点(法兰克福)→ 边缘节点处理(或转发到就近的 API)→ 返回。延迟降到 30~50ms。

以 Cloudflare Workers 为例,它在全球 300+ 个城市有节点。用户发请求,系统自动路由到最近的节点,完全不用你管。


实战:把首屏从 2.3s 压到 0.8s

我的项目是这样的:一个资讯站,SSR 渲染,API 调用在后端 Node.js 服务。用户主要分布在国内和东南亚。

问题是国内用户还好,东南亚用户访问,延迟直接 400ms+。SSR 的 HTML 生成要 200ms,加上网络延迟,首屏直接破 2 秒。

第一步:边缘缓存 HTML

Cloudflare Workers 支持边缘缓存 SSR 页面。把 HTML 缓存在边缘节点,用户请求直接命中缓存,不用回源。

// workers/cache-html.js
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const cache = caches.default
  const cacheKey = new Request(request.url)

  // 尝试命中缓存
  let response = await cache.match(cacheKey)

  if (!response) {
    // 缓存未命中,fetch 回源
    response = await fetch(request)

    // HTML 页面缓存 5 分钟,API 缓存 1 分钟
    const ttl = request.url.includes('/api/') ? 60 : 300
    response = new Response(response.body, response)
    response.headers.set('Cache-Control', `public, max-age=${ttl}`)

    // 写入缓存
    event.waitUntil(cache.put(cacheKey, response.clone()))
  }

  return response
}

效果:东南亚用户首屏从 1.8s 降到了 0.6s。缓存命中后,边缘直接返回,不用跨洋请求。

第二步:边缘做数据聚合

有些页面需要调多个 API,比如文章详情页要调:文章内容 API、点赞数 API、评论数 API。传统方式是串行请求。

边缘节点支持并行请求,而且离用户近,并行调用的总延迟远低于从用户设备直接发起。

// workers/article-aggregate.js
async function handleRequest(request) {
  const url = new URL(request.url)
  const articleId = url.searchParams.get('id')

  // 边缘并行请求三个 API
  const [articleRes, likeRes, commentRes] = await Promise.all([
    fetch(`https://api.example.com/articles/${articleId}`),
    fetch(`https://api.example.com/articles/${articleId}/likes`),
    fetch(`https://api.example.com/articles/${articleId}/comments`)
  ])

  const [article, likes, comments] = await Promise.all([
    articleRes.json(),
    likeRes.json(),
    commentRes.json()
  ])

  return new Response(JSON.stringify({ article, likes, comments }), {
    headers: { 'Content-Type': 'application/json' }
  })
}

注意:边缘节点内存有限(Cloudflare Workers 免费版 128MB),大文件处理不适用。但做数据聚合、轻量逻辑非常合适。

第三步:A/B 测试和个性化也在边缘做

以前做 A/B 测试,要么在后端 nginx 判断,要么在前端 JS 切换。但 nginx 判断还是得回源,前端切换有白屏。

边缘节点可以直接在请求层面判断用户特征,返回不同版本,完全没有回源延迟。

// workers/ab-test.js
async function handleRequest(request) {
  const url = new URL(request.url)

  // 从 Cookie 读取用户分组,没有则随机分配
  let group = getCookie(request, 'ab_group')
  if (!group) {
    group = Math.random() > 0.5 ? 'A' : 'B'
  }

  // 构造新请求,带上分组信息
  const newReq = new Request(request.url, {
    headers: { ...request.headers, 'X-AB-Group': group }
  })

  const response = await fetch(newReq)

  // 首次访问,设置 Cookie
  const newRes = new Response(response.body, response)
  if (!getCookie(request, 'ab_group')) {
    newRes.headers.set('Set-Cookie', `ab_group=${group}; Path=/; Max-Age=${60*60*24*30}`)
  }

  return newRes
}

不是所有场景都适合边缘计算

说完了好的,说点实际的。边缘计算不是银弹,以下场景不太适合:

  1. 需要大量计算的:边缘节点算力有限,复杂的图像处理、视频转码别指望它
  2. 强状态依赖的:需要精确 session 管理、有状态连接的场景,传统服务端更稳
  3. 数据一致性要求高的:边缘缓存带来的是最终一致性,不是强一致性

那适合哪些:静态资源缓存、API 聚合、A/B 测试、认证 token 验证、个性化内容选择、轻量业务逻辑。


怎么判断你的项目要不要上边缘

有个简单的判断标准:

  • 用户分布在多个大洲?→ 上
  • 首屏有明显的网络延迟瓶颈?→ 上
  • 页面需要调多个 API 聚合?→ 上
  • 业务逻辑简单,没有复杂状态?→ 上

反之,用户都在同一个地区、后端逻辑复杂、对数据一致性要求极高的,边缘计算带来的收益有限,别为了上而上。


下一步:从小处开始

如果你想试试边缘计算,建议从最简单的地方入手:把静态资源的缓存策略在边缘优化一下,或者选一个高频访问的接口,在边缘做个简单聚合。跑一段时间看数据,再决定要不要把更多逻辑迁移过去。

别一上来就全量迁移,小步快跑才是正经事。

评论区

0 条评论

登录后可评论。

阿速·性能优化 28 阅读