Skip to content

feat: SW 更新后自动 reload + 隐私友好的 Cloudflare Web Analytics#98

Merged
chaxus merged 1 commit into
mainfrom
fix/sw-freshness
Jul 5, 2026
Merged

feat: SW 更新后自动 reload + 隐私友好的 Cloudflare Web Analytics#98
chaxus merged 1 commit into
mainfrom
fix/sw-freshness

Conversation

@chaxus

@chaxus chaxus commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

背景

两个独立的小问题,都与"部署后用户拿到的是否是最新版本 + 隐私友好的访问统计"有关。

改动

1. SW 更新后自动 reload(修「要再手动刷一次才生效」)

每次部署 bin/build.sh 会用新的 CACHE_VERSION 重建 sw.js,新 SW skipWaiting() + 接管客户端触发 controllerchange。此前当前页仍渲染旧缓存构建,直到用户手动刷新。

新逻辑在 controllerchange 时 reload 一次,三重保护:

  • 仅真更新:启动时已有 controller 才算新构建接管(首次安装不 reload)
  • 只 reload 一次reloadingForUpdate 兜底
  • 绝不在文档打开时 reloadgetDocmentObj().fileName 非空则跳过,避免丢未保存编辑;落地页 fileName 为空,reload 无感

2. 隐私友好的 Cloudflare Web Analytics(新增 lib/analytics.ts

刻意不用 Google Analytics——本项目卖点就是本地、无服务器、隐私。Cloudflare beacon 无 cookie、无需同意横幅(GDPR 友好)。仅在同时满足两条时加载:

  • 配置了 VITE_CF_BEACON_TOKEN(未设 → 完全 tree-shake,fork / 本地开发零外部请求、无追踪)
  • 是顶层独立页面 → embed / iframe 模式绝不加载(否则会把宿主站访客算到我们头上)

token 是公开的客户端值,构建时从 env 注入安全。CI 通过 vars.VITE_CF_BEACON_TOKEN 传入。

影响面

  • 未配置 token 的部署 / fork:行为完全不变,无任何外部请求
  • 文件:index.ts lib/analytics.ts(新)vite-env.d.ts(新)pages-build-site.yml;含两篇 docs/explorations/ 记录
  • 无既有逻辑改写,纯增量

测试

  • pnpm run lint:ts / format:check
  • 部署验证 SW 自动 reload(落地页无感刷新、文档打开时不刷新)

🤖 Generated with Claude Code

Two independent changes to the standalone app entry:

1. SW freshness — after a deploy the new service worker skipWaiting()s and
   claims clients but never reloads the already-rendered page, so users keep
   seeing the previously-cached build until a manual refresh (the "refresh once
   more and it's fixed" symptom, which is what surfaced the stale PPTX font
   bug). index.ts now reloads once on `controllerchange`, guarded so it fires
   only on a real update (not first install), only once, and never while a
   document is open (a reload would discard unsaved edits).

2. Analytics — add cookieless Cloudflare Web Analytics (lib/analytics.ts)
   instead of Google Analytics, to stay consistent with the local-only privacy
   pitch (no cookies, no consent banner). The beacon loads only when a token
   (VITE_CF_BEACON_TOKEN) is set AND the app is top-level (never in embed
   iframe). With no token the whole beacon path is tree-shaken out, so the
   default build ships tracking-free. pages-build-site.yml injects the token
   from a repo variable.

Verified end-to-end with chrome-devtools: first-install no reload, update
reload once, doc-open no reload; beacon injects top-level, absent in embed,
absent (tree-shaken) with no token. lint:ts + sw-routing tests + build pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chaxus chaxus merged commit cfc9dcb into main Jul 5, 2026
1 of 2 checks passed
chaxus added a commit that referenced this pull request Jul 5, 2026
Includes two docs carried in from #98 (privacy-analytics, sw-stale-build)
that were never formatted.
chaxus added a commit that referenced this pull request Jul 5, 2026
Includes two docs carried in from #98 (privacy-analytics, sw-stale-build)
that were never formatted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant