事情是这样的

我同时维护着两个域名:

  • 101229.xyz —— 自己买的顶级域名
  • k1f.is-a.dev —— 免费领的二级域名

它们指向同一个东西:Cloudflare Pages 上的同一个 Hexo 博客。DNS 都是 Cloudflare,CDN 也是 Cloudflare,甚至清除浏览器缓存后测试,结果还是一样——

101229.xyz 加载首页大图,比 k1f.is-a.dev 快了十几秒。

十几秒是什么概念?在网页加载的世界里,这已经是从”秒开”到”想关页面”的差距了。

我一开始以为是 is-a.dev 这个第三方服务的问题。但当我用 Cloudflare Pages 自带的 *.pages.dev 子域名测试时,发现它也很慢,和 is-a.dev 半斤八两。

这就很有意思了。三个域名,同一个后端,同一个 CDN,同一个浏览器,为什么差距这么大?


第一步:排除法——不是 DNS 的问题

我先用 digcurl -w 做了对比测试。

DNS 解析时间上,三个域名确实有差异,但差距在毫秒级别,不是十几秒的量级。101229.xyz 可能快个几十毫秒,但这解释不了秒级的差距。

而且 pages.dev 也是 Cloudflare 自己的域名,DNS 解析应该是最优的,但它依然慢。

所以,问题可能不在 DNS 层


第二步:框架加载正常,图片是罪魁祸首

我打开 Chrome DevTools 的 Network 面板,发现了一个关键线索:

HTML、CSS、JavaScript 的加载时间,三个域名差不多。 框架几乎是同时渲染出来的。

图片的加载时间101229.xyz 和另外两个域名之间,差距巨大。

这说明瓶颈不在页面骨架的传输上,而在图片资源的获取策略上。


第三步:发现缓存头的秘密

我用 curl -I 查看响应头,发现了问题所在。

Cloudflare Pages 对静态资源的默认缓存策略是:

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

这个 must-revalidate 的意思是:每次请求图片,浏览器都必须向服务器发一个验证请求(If-None-Match),确认资源有没有变化。

对于 Hexo 生成的大图,这个验证过程虽然最终返回 304 Not Modified(资源没变),但往返的网络延迟仍然存在。如果首页有十几张图,这个延迟会线性累积。

但这里有个疑问:三个域名都是 Cloudflare Pages,为什么只有 101229.xyz 不受这个默认策略的拖累?


第四步:Zone 的边界——自定义域名的隐藏优势

我查了一下 Cloudflare 的文档,发现了一条关键信息:

pages.dev 不在你的 Zone 里,所以你的规则不会在那里生效。

这句话解释了核心差异:

  • 101229.xyz 是我自己的 Cloudflare Zone。我可以给它加 Cache Rule,把图片的缓存时间设成一年,让浏览器直接从本地磁盘读取,不需要发任何网络请求
  • *.pages.dev 是 Cloudflare 的共享 Zone,我无法覆盖它的默认缓存策略。
  • k1f.is-a.dev 虽然是自定义域名,但 is-a.dev 本身是第三方管理的域名,它的 DNS 架构可能多了一层 CNAME 跳转,而且同样不在我的 Zone 里,享受不到我的缓存优化。

也就是说,自定义域名快,不是因为它本身有什么魔法,而是因为它在你的控制范围内,你可以关掉拖慢速度的功能、可以自定义缓存策略、可以预热边缘节点。

pages.dev 和免费二级域名,虽然表面上也是 Cloudflare 的服务,但它们是共享资源,走的是”默认配置”,你无法干预。


第五步:Tiered Cache 的暗示

Cloudflare Pages 的文档里有这样一句话:

静态资源会自动从 Tiered Cache 提供,你不需要为自定义域名单独启用它。

注意措辞——它说的是”为自定义域名“。虽然理论上 pages.dev 也应该走 Tiered Cache,但自定义域名的缓存策略可能更激进、预热更充分。而 pages.dev 作为共享域名,缓存命中率可能更低,因为下面托管的项目太多,缓存被频繁淘汰。

这可能是另一个造成差距的因素,但我没有直接证据,只能说可能是


第六步:那 is-a.dev 呢?

is-a.dev 是第三方免费二级域名服务,它的 DNS 架构可能是这样的:

1
k1f.is-a.dev → is-a.dev 的权威 NS → 可能还有一层 CNAME → Cloudflare Pages

多一层 CNAME 就多一次 DNS 查询。如果 is-a.dev 的权威 DNS 服务器响应慢,或者节点离用户远,每次访问都要多等几百毫秒。虽然这不足以解释十几秒的差距,但它可能是雪上加霜的因素。


总结:三个域名,三种”身份”

101229.xyz *.pages.dev k1f.is-a.dev
Zone 归属 我的 Cloudflare Zone Cloudflare 共享 Zone 第三方 Zone
缓存策略可控 ✅ 可以自定义 ❌ 只能接受默认 ❌ 受第三方限制
DNS 链路长度 最短 中等 可能多一层
Tiered Cache 明确支持,可能更优 理论上支持 不确定
实际图片加载 快(本地缓存) 慢(每次验证) 慢(每次验证 + DNS 多跳)

给我的教训

  1. 生产环境一定要用自定义域名。 pages.dev 适合开发和预览,但不适合对速度有要求的场景。
  2. 缓存策略比 CDN 节点更重要。 即使同一个 CDN,不同的缓存头也能造成十几秒的差距。
  3. 免费的东西有隐形成本。 is-a.devpages.dev 虽然不要钱,但你在性能优化上失去了控制权。

最后

这个问题我折腾了好几天,从怀疑 DNS、怀疑浏览器、怀疑 Hexo,到最后发现是缓存策略和 Zone 边界的问题。

如果你也在用 Cloudflare Pages + 免费域名,并且觉得图片加载慢,不妨检查一下你的缓存头。也许,花几十块钱买个域名,比优化代码更能解决问题。

有时候,最快的优化不是写更好的代码,而是买对的基础设施。

(AI生成)