很多博客都会有一个模块:
热门文章 / Trending / Most Read。
问题是,这个“热门”通常是怎么来的?
答案往往并不让人舒服:
第三方统计脚本、跨站追踪、用户画像、行为分析。
而我的博客选择了另一条路。
我希望知道哪些文章更受欢迎,但我不希望知道“谁”在读。
这篇文章,我想完整讲清楚:
在不追踪用户的前提下,我是如何计算“热门文章”的。
一、我不想用的那套东西
我明确排除了以下方案:
-
Google Analytics / GA4
-
任何需要加载第三方 JS 的统计服务
-
基于用户身份、登录态、跨页面行为的分析
-
以 Cookie / Fingerprint 为核心的用户追踪
原因很简单:
-
对博客来说,这些信息并不必要
-
引入的复杂度远高于实际价值
-
与我对隐私与数据最小化的理解相冲突
我真正想要的,只有一件事:
哪些文章,在最近一段时间内,被更多人读过。
二、先明确一个事实:博客不需要“精确统计”
很多人一提统计,就会追求“绝对准确”。
但对博客而言,这是一个伪命题。
我不需要知道:
-
某个用户读了多久
-
是否滚动到第几行
-
是否二次回访
-
是否来自哪个广告渠道
我只需要一个稳定、可比较的信号。
热门文章不是“精确数字”,而是“相对趋势”。
三、我的核心原则
在设计统计方案前,我给自己定了四个原则:
-
不识别用户
-
不跨页面追踪
-
不依赖第三方
-
不被缓存/CDN 干扰
只要违反其中任何一条,这套方案就不成立。
四、阅读统计的最小实现
1️⃣ 不在页面渲染时计数
页面可能被:
-
CDN 缓存
-
静态化
-
预渲染
所以我不会在 PHP 渲染阶段统计阅读数。
取而代之的是:
页面加载完成后,通过一次 AJAX 请求,单独记录一次“阅读事件”。
这样:
-
页面是否缓存无关紧要
-
统计逻辑与内容完全解耦
2️⃣ 只做“文章级别”的计数
我不关心用户是谁,只关心:
-
这篇文章是否被“读过一次”
因此我只在文章维度存两类数据:
-
总阅读数
-
按天聚合的阅读数
不记录:
-
用户 ID
-
IP 原文
-
访问路径
-
行为序列
3️⃣ 非侵入式去重
为了避免刷新刷量,我只做了两件事:
-
24 小时 Cookie 去重(只作用于当前文章)
-
分钟级 IP Hash 限速(防脚本刷)
注意几点:
-
IP 不落库,只做 Hash
-
Cookie 不跨文章、不跨站
-
没有任何“用户画像”的可能性
五、为什么我要引入「7 天热度」
如果只用“总阅读数”,会发生一件事:
老文章会永久霸榜。
这对博客并不健康。
所以我引入了一个非常简单的概念:
只看最近 7 天,这篇文章被读了多少次。
实现方式也很朴素:
-
每天一个计数
-
只保留最近 7 天
-
自动清理旧数据
这带来一个重要结果:
-
新文章有机会被看见
-
老文章如果重新被讨论,也能再次上榜
六、我的「热门文章」算法
我没有使用复杂模型,只用了一个可解释、可写进博客的公式:
它有几个特点:
-
近期行为权重大
-
历史内容仍有价值
-
不会被一次流量峰值长期污染
更重要的是:
任何读者都可以理解这个规则。
七、这套方案我“刻意没有做”的事
为了保持克制,我主动放弃了很多看似“高级”的功能:
-
不做实时榜单
-
不做用户停留分析
-
不做转化路径
-
不做内容 A/B Test
因为这些都意味着:
-
更多数据
-
更复杂系统
-
更强的追踪动机
而这已经偏离了“博客”这个媒介的本质。
八、这套方案对我来说意味着什么
对我而言,这不仅是一个统计方案,更是一种态度:
-
内容比用户重要
-
趋势比画像重要
-
最小数据原则是工程美德
我依然可以知道哪些文章更受欢迎,
但我不需要知道是谁在读。
九、如果你也在写博客
如果你也在写博客,我的建议是:
在引入统计之前,先问自己一句话:
“我真的需要知道这么多吗?”
很多时候,一个简单、干净、可解释的方案,
反而更适合长期写作。






