最近在浏览 GitHub Profile README 时,发现自己主页的 github-readme-stats 用不了,anuraghazra/github-readme-stats 这个经典项目主要是用来展示个人统计卡片,比如 Stars、Forks、Followers 和 Top Languages。然而,这个项目的公共 Vercel 实例(github-readme-stats.vercel.app) 近年来经常出现不稳定情况——尤其是 2025 年底,有多个 Issue 报告显示卡片加载失败或显示错误
究其原因,主要还是 GitHub API 的速率限制问题。未经认证的请求每小时仅限 60 次,而公共实例被成千上万的用户共享,极易触发 403 Forbidden。即使项目本身实现了缓存,流量高峰期也难以完全避免中断。这让许多开发者在更新 Profile 时感到困扰:卡片时好时坏,影响了展示效果。
为什么需要自托管替代?
github-readme-stats 是一个优秀的开源项目,但依赖公共部署的痛点显而易见:
- 共享限流:所有用户共用同一个 API 配额,热门时容易崩。
- 不可控:无法自定义主题、缓存策略或添加个人化逻辑。
- 隐私与性能:数据通过第三方服务中转,虽然开源但仍存在潜在风险。
自托管是更可靠的解决方案:你拥有独立的部署实例,使用自己的 GitHub Token(可选)来提升限额(从 60/h 提升到 5000/h),并通过缓存机制进一步优化。
Cloudflare Workers:完美的自托管平台
Cloudflare Workers 是边缘计算的理想选择:
- 免费阶层充足:每天 10 万请求足够个人使用,甚至支持中等流量。
- 全球边缘网络:响应延迟极低,SVG 加载几乎瞬间完成。
- 内置 KV 支持:轻松实现数据缓存,无需额外数据库。
- 零服务器运维:一键部署,无需管理 Node.js 环境或 Vercel 配额。
基于这些优势,我参考了社区的一些实现,整理了一个简洁、高效的 Cloudflare Worker 脚本。它功能聚焦于核心统计:Stars、Forks、Public Repos、Followers、Gists,以及 Top 5 Languages,并采用 Tokyonight 主题,确保视觉美观且垂直居中对齐完美。
源代码 Gist:gist.github.com/chenxuan520…
核心实现剖析
脚本的核心逻辑如下:
-
参数解析与基本防护:
- 通过
?username=yourname获取用户名。 - 无参数时返回友好提示。
- 拦截 favicon 请求,避免浏览器控制台错误。
- 通过
-
缓存机制(KV):
- 如果绑定了
STATS_CACHEKV Namespace,先查缓存(TTL 60 秒)。 - 命中直接返回,添加
X-CF-Worker-Cache: HIT调试头。 - 未命中时异步写入缓存(使用
ctx.waitUntil非阻塞)。
- 如果绑定了
-
GitHub API 调用:
- 支持可选
GITHUB_TOKEN环境变量,提升限额。 - 先获取用户基本信息(followers、public_repos 等)。
- 再获取前 100 个仓库(per_page=100),计算 Stars/Forks。
- 统计语言分布,取 Top 5 并计算百分比。
- 支持可选
-
SVG 生成优化:
- 使用
dominant-baseline: middle实现完美垂直居中(避免传统dy偏移的字体兼容问题)。 - XML 转义函数防止用户名特殊字符破坏 SVG。
- 进度条使用渐变色数组,支持多种语言高亮。
- 固定尺寸 495x195,圆角边框,Tokyonight 配色方案。
- 使用
-
错误处理:
- 特别捕获 403 无 Token 情况,返回友好提示引导配置 Token。
相比原项目,这个实现更轻量(单文件、无外部依赖),聚焦于统计卡片而非多卡片支持,适合大多数 Profile README 需求。
部署步骤(只需 5 分钟)
-
创建 Worker:
- Cloudflare Dashboard → Workers & Pages → Create Worker。
- 粘贴完整代码(见文末 Gist 链接),保存并部署。
-
可选配置(强烈推荐):
- GITHUB_TOKEN:GitHub 生成一个无权限 Classic Token,添加到 Worker Variables。避免限流。
- KV 缓存:创建 KV Namespace(如
github_stats),绑定变量名STATS_CACHE。
-
使用方式: your-worker.your-subdomain.workers.dev/?username=y… 在 README 中嵌入:

示例效果(以原作者 chenxuan520 为例):
进一步思考与扩展
- 为什么选择 REST 而非 GraphQL?REST 更直观,且单次请求即可获取所需数据。GraphQL 虽强大,但对于简单统计 overhead 较大。
- 缓存策略:60 秒 TTL 平衡了实时性和性能。如果你的仓库更新不频繁,可延长到 300 秒。
- 自定义潜力:你可以轻松修改主题颜色、添加贡献热力图(需额外 API)、或支持暗黑/亮色切换。
- 限流终极解决方案:结合 Token + KV,基本无忧。即使高流量,也远优于公共实例。
这个方案本质上是“个人化基础设施”的体现:在 Serverless 时代,我们不再依赖单一公共服务,而是通过几行代码构建属于自己的可靠工具。
源代码 Gist:gist.github.com/chenxuan520…
欢迎大家试用、Fork 并反馈。如果你在部署中遇到问题,评论区留言,我会尽力解答。让我们一起让 GitHub Profile 更稳定、更个性!