---
title: "给连载小说做了一个轻量 SVG 访客统计"
canonical_url: "https://hoxi.ai/zh/blog/lightweight-svg-analytics-for-serial-novels"
type: "blog"
locale: "zh"
description: "今晚折腾了一个小项目：SVGStat 也算赶在 Fable 5 开始按量收费之前，狠狠薅了一把，撸到现在。 起因非常朴素，甚至有点寒酸： 我在 GitHub 上连载 《底层重构》 ，写的时候挺起劲，更新也一直没断，但有一个问题特别真实： 我是真不知道到底有没有人在看。 不是那种“后台有几万 UV 但我还在焦虑”的不知道，是真的不知道。 不知道有多少人看。 不知道是新读者还是回头客。"
published_at: "2026-08-29T12:58:05.000Z"
updated_at: "2026-10-18T13:03:47.000Z"
---

# 给连载小说做了一个轻量 SVG 访客统计
> 今晚折腾了一个小项目：SVGStat 也算赶在 Fable 5 开始按量收费之前，狠狠薅了一把，撸到现在。 起因非常朴素，甚至有点寒酸： 我在 GitHub 上连载 《底层重构》 ，写的时候挺起劲，更新也一直没断，但有一个问题特别真实： 我是真不知道到底有没有人在看。 不是那种“后台有几万 UV 但我还在焦虑”的不知道，是真的不知道。 不知道有多少人看。 不知道是新读者还是回头客。

## 今晚折腾了一个小项目：SVGStat

也算赶在 Fable 5 开始按量收费之前，狠狠薅了一把，撸到现在。

起因非常朴素，甚至有点寒酸：

我在 GitHub 上连载 [《底层重构》](https://github.com/aihop/Refactoring-the-Self)，写的时候挺起劲，更新也一直没断，但有一个问题特别真实：

我是真不知道到底有没有人在看。

不是那种“后台有几万 UV 但我还在焦虑”的不知道，是真的不知道。

不知道有多少人看。

不知道是新读者还是回头客。

不知道大家是手机看还是电脑看。

不知道是路过瞅两眼，还是半夜两点拿我小说当电子榨菜。

最离谱的是，有时候你明明觉得自己写到高潮了。

内心预期应该是“读者狂喜，剧情发酵，评论区爆炸”，结果现实是静悄悄，安静得像我刚发完工资的钱包。

于是我开始想：

能不能搞一个特别轻的统计方案？

别整一堆埋点。

也别非得有个完整网站后台。

我只想在页面里放一个东西。

然后它告诉我：

**到底有没有人看。**

宵夜过后这个想法越想越歪，最后就长成了现在这个项目。

---

## 这项目是干嘛的？

一句话：

**把统计能力做成一张图片。**

对，就是图片。更准确一点说，是 SVG。

你可以把一个统计地址直接塞进：

- GitHub README
- Markdown 文档
- 静态网站
- 文档站
- 落地页
- 甚至任何能放  的地方

然后它会显示一个动态计数器或者徽章，比如：

- 访问量
- 下载量
- 某个页面的阅读次数
- 你自己定义的指标

## 为什么不用现成统计工具？

喜欢折腾。

喜欢轻的东西。

喜欢干净简洁。

当然，还有一个原因：自己做，比较好玩。

## 这个项目目前做了什么？

现在这个项目已经能跑起来了，核心能力包括：

### 1. 实时 SVG 计数器

最核心的能力，就是把统计做成一张能直接嵌进页面里的 SVG。

```
/svg/{projectSlug}/counter/visits.svg
```

图片被请求一次，就记一次，再直接返回一张图。

放进 README、Markdown、静态页面里，它就是一张活的统计图。

### 2. 用 page_id 做页面归因

GitHub 的图片代理很不老实。

很多时候你只知道图片被请求了，但不知道到底是哪一页在请求。

所以项目里加了 `page_id`。

比如我在《底层重构》第 15 章里，会这样引用：

```
![Visits](https://svgstat.com/svg/refactoring-the-self/counter/visits.svg?page_id=chapters/15-first-boundary&label=Visits)
```

演示：

这样我就知道，到底是第 15 章有人看，还是 README 有人看。

这个小参数，看起来不起眼，但对 GitHub 场景很关键。

### 3. 轻量 dashboard

我不只是想看一个数字涨没涨。

所以后面又接了一个很轻的分析面板，去看：

- PV
- UV
- Bot 数量
- 国家分布
- 设备和浏览器分布
- 最近的访问明细

你可以把它理解成：

前面的 SVG 是门口招牌，后面的 dashboard 才是真正看数据的地方。

---

## 技术上是怎么做的？

技术上其实也不复杂，核心就是一套很直接的组合：

- 后端：Go
- 高频计数：Redis
- 持久化数据：PostgreSQL
- 前端面板：Alpine.js + UnoCSS

为什么这么搭？因为它刚好适合这个场景。

Go 负责接请求、生成 SVG、吐回图片，干这种活很顺手。

Redis 负责高频计数，像 PV、UV、国家、设备这些热数据，先放它这里最合适。

PostgreSQL 负责项目、配置和持久化元数据，一个管“快变的”，一个管“存档的”，脑子会清楚很多。

UV 目前是基于 `IP + User-Agent` 做哈希，Bot 也做了一层简单识别。

不求绝对完美，但先把“到底是不是只有我自己在看”这件事搞明白。

---

## 现在回头看，这项目有点像什么？

有点像以前博客时代大家爱挂的访问计数器。

只不过这次我不满足于右下角那个“你是第 12345 位访客”。

我还想知道：

- 12345 里面有多少是真人
- 他们从哪来
- 他们看的是什么页面
- 他们用什么设备
- 哪些页面真的有人停留

所以它最后长成了一个“有前台展示能力的轻量分析系统”。

说严肃点，它是一个 SVG analytics platform。 说通俗点，它就是：

**给内容创作者和项目作者用的，体面一点的电子门铃。**

门铃响了，你至少知道门外不是风。

---

## 后面还想做什么？

目前项目已经能：

- 生成动态计数器
- 生成动态徽章
- 做 GitHub/Markdown 场景嵌入
- 做页面归因
- 看访客分析面板

后面还想继续补的东西包括：

- 更丰富的 SVG widgets
- 趋势图和图表视图
- 公共项目统计页
- 更完整的自托管体验
- 更适合创作者和独立开发者的展示模板

因为我越来越觉得，很多人不是不需要统计，而是不需要那么重的统计。

他们真正需要的是：

**一个轻量、直接、能放出去、还能看明白的东西。**

---

## 最后

这个项目的起点其实很简单。

不是大理想，不是商业蓝图，也不是什么“重新定义开发者分析”。

就是因为我连载小说，写了半天，不知道有没有人看。

如果你也在写博客、写文档、做开源项目、搭静态网站，或者连载点什么东西，这种轻一点的统计方式，可能也适合你。

很多项目的起点，并不是需求文档。

而是你盯着页面看了一会儿，心里突然冒出来一句：

**“所以，到底有没有人在看啊？”**

## 关于项目：

项目地址： [https://github.com/aihop/svgstat](https://github.com/aihop/svgstat)

在线体验： [https://svgstat.com](https://svgstat.com)

## 预览
