FIELD NOTE 03 / 03

2026.06.21 · 本期

边缘不是更快的服务器,而是更短的等待

把应用搬到边缘之前,先算清楚一毫秒从哪里来。关于延迟预算、静态优先与那些不该被边缘掩盖的取舍。

深绿色背景上有网格、弧形轨迹与发光节点,朱红色虚线贯穿其间,下方写着巨大的「边缘」。
封面插画 / FOLD Press

WORDS BY

Caz 设计与代码的慢笔记
发布
阅读
约 6 分钟
编号
NO. 003

FILED UNDER

返回文章列表

有一年我在东南亚旅行,住处的网络很不稳定。打开自己的博客要等三秒,明明只是一篇静态文章。那三秒里,浏览器先等待 DNS,再建立连接,再协商 TLS,最后才拿到一个几乎从不变化的 HTML 文件。我当时正在研究边缘部署,忽然意识到:我优化的是服务器响应时间,用户感受到的却是整段抵达过程。

边缘计算很迷人,因为它承诺把计算放得离用户更近。但「更近」本身不是目的。真正的问题是:在用户开始阅读之前,有多少不可避免的等待?以及,哪些等待其实是我们自己制造出来的?

延迟是一笔预算,不是一张排行榜

从浏览器发出请求到像素出现,时间大致花在这些地方:

  • DNS 解析与连接建立:几十到几百毫秒;
  • TLS 握手:一到两个往返;
  • 网络传输:由物理距离、拥塞和协议决定;
  • 服务端处理:从几毫秒到几秒不等;
  • 下载与解析 HTML、CSS、字体和 JavaScript;
  • 浏览器布局、绘制,以及主线程上的脚本执行。

边缘节点能显著影响其中的一部分,尤其是连接建立与服务端处理。它不能消除光速,也不能修复一个 2MB 的首屏 JavaScript 包。把数据库放到三十个区域,如果没有解决查询的 N+1 问题,用户依然可能在等同一张慢表。

所以我更愿意把性能当成预算来管理:

目标:4G 移动网络下 p75 LCP < 2.0s

连接与 TLS          ~ 300ms
TTFB                  < 500ms
首屏 HTML 下载        < 150ms
关键 CSS              已内联
字体                    1 个可变字重,swap
首屏 JS               < 20KB(或不加载)

这些数字不是普适标准,而是一个团队对「足够快」的共同定义。没有预算,优化就会变成零散的技巧;有了预算,才知道下一步该删什么。

静态优先,不是技术保守

这个博客本身是纯静态的。文章在构建时生成,部署到 Cloudflare Pages,页面没有运行时数据库,也没有服务端渲染。唯一必须运行的客户端 JavaScript,是用户主动切换主题时的一小段逻辑。

这不是因为动态能力不好,而是因为内容站点的绝大部分请求,根本不需要在请求发生时计算。 同一篇文章在一天内被一千个人阅读,生成一次就够了。构建时的确定性换来了运行时极低的复杂度和极小的故障面。

缓存策略也可以因此变得非常简单:

Cache-Control: public, max-age=0, must-revalidate

对 HTML 使用较短的校验缓存,让新文章尽快出现;对带内容哈希的 CSS、JS 和字体使用长缓存:

Cache-Control: public, max-age=31536000, immutable

真正重要的不是某个响应头模板,而是资源是否拥有稳定的身份。文件名里没有内容哈希的脚本,一旦设置长缓存,就在为未来的事故埋线;而静态资源的不可变缓存,只有在构建产物可预测时才有意义。

边缘也有边界

边缘最容易卖给人的故事是「把服务器搬到用户旁边」。实际工程里,你还要面对:

  • 数据一致性。 用户刚提交的评论,是否能在下一次请求里立刻看到?多区域写入会把这个简单问题变成分布式系统问题。
  • 冷启动与运行时。 边缘函数的冷启动通常很短,但并不是零;当函数依赖较大的包或需要初始化数据库连接时,开销会重新出现。
  • 可观测性。 请求散落在许多区域,日志、追踪和错误聚合必须跟上。否则你只是把问题分散到了更难排查的地方。
  • 成本模型。 边缘请求、出口流量和计算时间可能分别计费。一个在单区域便宜的架构,不一定在边缘便宜。
  • 安全边界。 把鉴权、限流和密钥管理分发到更多节点,意味着更多需要审计的表面。

这些不是反对边缘的理由,而是使用它的前提。边缘适合那些读多写少、状态轻、地理位置敏感的路径:静态资源、个性化但不敏感的重写、A/B 分流、图片变换、地理路由。至于需要强一致写入的核心事务,把它留在离数据最近的地方,通常更诚实。

场景 适合放在边缘吗 原因
静态文章与图片 是 内容不变,缓存收益高
地理重定向 是 决策轻,靠近用户
个性化推荐 视情况 延迟低,但依赖数据新鲜度
账户写入与支付 通常否 一致性与审计优先
大规模图像转码 视情况 算力与成本需要单独评估

测量用户真正经历的那一段

如果只看服务器指标,边缘会显得无所不能。可用户感知的是从点击到可读的时间。要接近这个真实体验,至少需要看:

  1. TTFB 的分布,而不是平均值。 p75 和 p95 暴露的是长尾,长尾才决定用户会不会离开。
  2. 分地区的 RUM 数据。 平均值会把网络条件截然不同的人混在一起。
  3. 实验室之外的设备。 一台中端安卓手机在 4G 网络上的表现,比办公室里的光纤 MacBook 更接近大多数访问。
  4. 首次与再次访问的差异。 缓存命中率、Service Worker、字体缓存都会改变结果。

在命令行里,我经常用一条简单的请求确认边缘是否按预期工作:

curl -s -o /dev/null \
  -w 'dns=%{time_namelookup}s connect=%{time_connect}s tls=%{time_appconnect}s ttfb=%{time_starttransfer}s total=%{time_total}s\n' \
  https://caz-blog.pages.dev/

它不能替代真实用户监控,但能让抽象的「边缘加速」变成一个可以观察的数字。如果 DNS 仍然要 300 毫秒,那么把所有逻辑搬到三十二个区域也不会让首屏提前一秒。

更短的等待,而不是更快的机器

边缘最吸引人的地方,不是配置面板里不断增加的节点数量,而是它迫使我们重新画出请求的路径。哪些计算必须发生在请求时?哪些结果可以提前生成?哪些状态可以从关键路径上移走?哪些 JavaScript 根本不必发送?

这些问题在单区域应用里同样成立,只是边缘让它们变得更明显。真正的性能工作从来不只是换一个更快的服务器;它是删掉一段不必要的旅程,让内容更早地出现在用户眼前。

以后再看到「部署到边缘,延迟降低 80%」这样的标语,我会先问:降低的是哪一段?用户能感知到吗?为此多出来的复杂性,值得吗?

如果答案清楚,边缘就是一把好工具。如果答案含糊,那 80% 可能只是把等待从一个地方挪到了另一个地方。