2026.06.10 (三)

✨ GPT-5.5 的摘要  

修正公开统计页面中访问和浏览量混在一起显示的问题,将基于30分钟会话的访问数与基于页面打开次数的浏览量分开,并整理成移动端也易读的仪表板记录。

做完公开博客统计页面之后,我马上发现了一个不舒服的地方。

数字确实出来了。

但数字的名称太容易混在一起。

访客、访问、浏览量、会话、page view。在博客界面上它们看起来很像,但在实际统计模型里并不是同一个东西。公开计数器如果把这些概念说得模糊,即使数字能正常显示,也很难让人信任。

一开始我以为“今日浏览量”“本月浏览量”“总浏览量”这样简单显示就够了。但侧边栏真正想展示的,更接近今天博客有多少次访问,而不是文章被打开了多少次。

访问和浏览量仍然混在一起的早期公开计数器卡片

所以我重新拆分了结构。

访问
-> 30分钟无活动后结束的会话

浏览量
-> 页面或文章被打开的次数

将访问和浏览量分开显示后的统计卡片

4943不是访问数

首先需要修正的是baseline的含义。

从Google Analytics拿来的4943这样的值是screenPageViews。也就是页面浏览量。如果把它显示成总访客数或总访问数,那就是错误的数字。

所以我同时整理了Worker和文档。

totalPageViews
-> GA screenPageViews baseline + D1 page views

totalSessions
-> GA sessions baseline + D1 sessions

访问和浏览量不能放在同一个baseline上。于是我新增了单独seed会话baseline的route。

/admin/seed-session-baseline

GitHub Actions的Worker部署流程里也加入了会话baseline seed步骤。如果Worker代码部署了,但baseline为空,公开页面上的总访问数就会看起来不正常。

直接使用/track响应

最初的结构有点绕。

客户端先用/track增加计数,再重新读取/analytics填充画面。这样因为缓存和请求顺序,刚刚反映的访问可能不会马上出现在屏幕上。读者看到时会像是“我刚打开页面,为什么今日访问没变?”

所以现在/track响应会一起返回最新的analytics payload。

流程变成这样。

页面加载
-> POST /track
-> Worker反映会话/浏览量
-> 同一个响应包含最新analytics
-> 客户端用该payload渲染侧边栏和当前页面浏览量

之后的周期性刷新仍然读取/analytics

也就是说,首屏优先使用刚刚更新过的payload。之后再用读取API跟随最新状态。

会话不能随着每次页面移动增加

浏览量可以随着读者移动到不同文章而增加。

但访问不同。同一个人在同一个博客会话里读了三篇文章,不应该变成三次访问。所以我在Worker里加入sessions表,用visitor hash和最后活动时间连接会话。

标准是30分钟。

最后活动后30分钟以内
-> 同一会话

超过30分钟
-> 新会话

这样侧边栏的今日/本月/总访问数会比page view更稳定。相反,文章级浏览量仍然按page path增加。

多语言页面也遵循同一原则。

/daily-review/...//en/daily-review/.../是同一篇文章的不同语言版本。浏览量key使用canonical path,同一会话内切换语言不会再增加访问数。

把仪表板改得更像表格

最初的统计页面以KPI卡片和条形列表为中心。

这并不差。但当访问和浏览量同时出现时,结构开始变得含糊。卡片变多后,移动端页面变长,也很难一眼看出哪个数字是某个期间的访问,哪个是浏览量。

所以我把上方比较区域改得更接近表格。

按期间整理访问和浏览量后的统计仪表板

期间        访问        浏览量
选择期间    n           n
今日        n           n
本月        n           n
总计        n           n

总计也拆成两行。

总计
-> 2026/06/09之后的直接统计

总计
-> 包含2026/06/09之前的统计

这两个含义不同。

直接统计是从公开维度开始进入D1之后的值。包含以前统计的总计,则是加上GA baseline后的公开总数。把它们混在一行里,数字会显得更大,但无法和详细维度对应。

所以仪表板说明也拆开了。

访问:排除30分钟内重复访问。浏览量:页面打开次数。
直接统计从2026/06/09开始。

让直接日期输入更好用

统计页面经常要改日期。

一开始我以为range=todayrange=monthrange=totalrange=custom按钮就够了。但要查看直接期间,就得一直改开始日和结束日。

所以我把输入做得更像一个小工具。

YYYY/MM/DD显示
隐藏的date picker
年/月/日segment选择
用ArrowUp / ArrowDown调整日期
用鼠标wheel调整日期
开始日和结束日范围clamp

外观仍然只是两个小输入框,但调整日期不那么烦了。

我也放弃了只有点击custom时才显示日期输入的方式。日期输入始终可见,点击preset按钮时日期会移动到对应范围。

这样更可预期。

详细维度分成标签页

详细维度全部展开会很乱。

页面、访客环境、来源、地区/语言都有用,但全部摆在一个屏幕上很难读。所以我把它们分成标签页。

页面
访客环境
来源
地区/语言

页面path可能很长,所以label加入title,并调整样式避免换行和省略破坏布局。以/开头的page dimension值会变成链接。

目标不是做一个华丽的dashboard。

我只是想在手机上打开时,也能快速看到哪些文章被读、今天访问数是多少、浏览量大概多少。

多语言标签也一起对齐

统计页面不只有韩语。

还有/en/analytics//ja/analytics//zh-Hans/analytics/等active locale页面。所以“访问”“浏览量”“30分钟会话”“GA浏览量 + D1”这样的标签,也要同步到各locale的front matter。

如果漏掉这一点,结构虽然改了,其他语言页面里还会留下旧文案。

在多语言博客里,修改一个功能并不是只改一个页面。同一界面存在于多个locale里,标签含义也必须一起移动。

确认过的内容

主要确认了渲染和数字含义。

node --check cloudflare/ga-stats-worker.js
node --check assets/js/custom/analytics-dashboard.js
node --check assets/js/custom/visitor-stats.js
bundle exec jekyll build
Cloudflare Worker deploy
GitHub Pages deploy

确认标准如下。

侧边栏是否把sessions显示为访问
文章级浏览量是否继续使用page view
总访问和总浏览量是否使用不同baseline
直接统计总计和包含GA的总计是否分开
直接期间输入是否不与today/month/total preset冲突
移动端期间/访问/浏览量表格是否不横向溢出

这次工作之后,统计页面反而安静了一些。

数字更多了,但更不容易混淆。访问就是访问,浏览量就是浏览量。总计也是总计,但直接统计总计和包含历史的总计不是一个东西。

重点不是让数字看起来更大。

而是不隐藏每个数字的含义。

留下评论