perf: 开启 Workers Cache 缓存 favicon,并给动态接口兜底 no-store

背景:favicon 此前只有 Cache-Control: max-age(仅浏览器缓存),
CF 边缘不缓存 Worker 响应 → 每次请求都进 Worker → 第一句就是 KV.get。
友圈页按友链数放大,KV 读量被显著放大。

★ 关键纠错:zone 级 Cache Rules 对 Worker 响应**完全无效**。
原因是 Worker 位于 zone 缓存之前("Workers sits in front of cache"),
且 Worker 直接生成响应时不发 fetch 子请求,cache status 只能是 none/unknown。
查证 CF 官方文档后确认,正确方案是 [cache] enabled = true(Workers Cache,
2026-07 上线,需 wrangler >= 4.69)。

改动:
- wrangler.toml: 新增 [cache] enabled = true;compatibility_date 提到 2026-07-24
- package.json: wrangler ^3.99 → ^4.147,workers-types ^4 → ^5(peer 要求)
- index.ts: 抽出 dispatchRequest;新增 ensureCachePolicy 兜底
  ★ 这一步是必须的:Workers Cache 遵循 RFC 9111 含**启发式缓存**,
    没带 Cache-Control 的响应也可能被缓存。实测 /api/v2/comments 开启后
    立刻被缓存(HIT, age:29)→ 用户发的新评论看不见。
    现在白名单式兜底:已显式声明可缓存的(favicon 的 s-maxage)保留,
    其余一律补 no-store。

验证(中转机实测,已清空 zone 的无效 cache rule):
- /api/favicon      → MISS → HIT,age 递增(Worker 不再执行,KV 读归零)
- /api/v2/comments  → BYPASS ×3,cache-control: no-store
- /api/v2/conf      → BYPASS,no-store
- /api/v2/healthz   → BYPASS,no-store
This commit is contained in:
zqlit committed 2026-10-06 13:28:56 +08:00
1 parent d2f1d176af
commit ca2fb7163d
3 files changed
+91 -26

No files matched your search

+18 -1
View File
@@ -1,6 +1,23 @@
name = "artalk-cf"
main = "src/index.ts"
compatibility_date = "2025-06-01"
compatibility_date = "2026-07-24"
# ---------------------------------------------------------------------------
# ★ Workers Cache —— 缓存 Worker 自己生成的响应(无需回源 fetch)
#
# 为什么必须开:Worker 位于 zone 缓存之前("Workers sits in front of cache"),
# 所以 **zone 级 Cache Rules / Page Rules 对 Worker 响应完全无效**。
# 想让 /api/favicon 这类「Worker 直接返回」的响应被边缘缓存、从而不再执行
# Worker(省 KV 读 + 省 Worker 请求),唯一正解是这个 [cache] enabled。
#
# 生效条件(缺一不可):
# 1. 这里是 fetch 处理器(scheduled 等不参与缓存)
# 2. 响应带可缓存的 Cache-Control(本项目已带 s-maxage=86400)
# 3. 只缓存 GET/HEAD;带 Set-Cookie 的响应自动绕过
# 验证:连续两次 curl -I,应依次看到 cf-cache-status: MISS → HIT
# ---------------------------------------------------------------------------
[cache]
enabled = true
# ---------------------------------------------------------------------------
# D1 (必须) 创建:npx wrangler d1 create artalk-cf