给 WordPress 博客做了个数据大屏,我踩了这三个坑

2026年7月27日17:32:50 发表评论
微信搜一搜 ts小陈

我的博客(kqwq.com)跑了几年,累计 1000+ 篇文章、1500+ 条评论。一直想有个「数据大屏」把这些信息可视化出来——看看自己这些年都写了啥、读者从哪来、啥时候最勤快。折腾了一周,总算做出了一个单文件的 dashboard.php。这篇文章记录从 0 到 1 的过程,以及几个让我抓狂的坑。

给 WordPress 博客做了个数据大屏,我踩了这三个坑

一、为什么不直接用插件?

市面上有 WP Statistics、MonsterInsights 之类的统计插件,但它们要么要埋第三方脚本、要么功能模板化、要么数据不归自己。我更想要一个完全自己掌控、能展示我真正关心的维度(比如按省份、按高频词、按发文时段)的页面。

于是决定:自己写。

二、技术方案:单文件 PHP + ECharts

整个大屏就是一个 dashboard.php,核心思路:

  • 直连数据库:自动读取 WordPress 根目录的 wp-config.php 拿到 DB 账号,不依赖任何 WP 插件或 REST API。
  • 可视化:用 ECharts 5.5.0 画图,评论 / 标签词云用 echarts-wordcloud。
  • 双层缓存:服务器开了 Memcached,再套一层文件缓存兜底,数据半个月刷新一次(避免每次访问都跑几十个 SQL)。想强制刷新就访问 ?refresh=1
  • 访客省份:用主题 xiaochen 自带的纯真 IP 库(ip2c.php + 25qqwry.dat)解析评论 IP,不依赖插件。
  • 中国地图:下载本地 china-geo.json 随文件一起部署,避免运行时再请求外部接口。

三、大屏里都有啥

  • 📊 数据概览卡片(文章数、评论数、标签数……)
  • 📈 每月发文趋势(从 2021 年 4 月起,更早月份数据异常、不具参考性)
  • 📂 分类文章分布、🏷️ 热门标签 Top 10
  • 💬 评论高频词 TOP 15(「不错」「非常好」这类出现最多的词)
  • 🗺️ 访客省份分布(中国地图 + 进度条)
  • 📅 每周发文分布、⏰ 发文时段热力图(热力图 / 按星期 / 按小时 三视图切换)
  • 📆 年度数据对比、🖼️ 媒体类型分布
  • 🔥 热评文章 Top 10、🕐 最新文章
  • ☁️ 评论 / 标签漂浮词云

顶部还有吸顶导航,品牌名居中,带一个「内容导航」下拉,一键跳到任意板块。

四、开发中的几次迭代

这部分最有意思,因为几乎每个功能都改了好几版。

1. 「评论话术」其实是高频词 一开始想做「评论话术前十」,后来发现更准确的说法是评论内容高频词——比如有 10 个人评论「不错」、8 个人评论「非常好」。于是改成分词统计 TOP 15。

2. 词云:从静态到「真漂浮」 最早用 echarts-wordcloud,但它只有进场动画,不会一直动。加定时器重排也只是抖动。最后干脆用纯 HTML/CSS 重写:每个词是绝对定位的 span,用 @keyframes 做 ±40px 的循环漂移 + 整体 55 秒呼吸式微旋转。效果终于「活」了。

3. 热力图:从乱到精致 初版热力图时间轴太密、色阶打架,看着很乱。重做后:x 轴每 3 小时标一次、色阶移到右侧竖向、单元格加描边。又加了「热力图 / 按星期 / 按小时」三视图切换。

4. 顶部导航 从最初一个简单的「返回博客首页」按钮,扩展成带「内容导航」下拉菜单(16 个板块锚点跳转),品牌名做到居中显示。

五、三个让我抓狂的坑

坑 1:浏览器缓存,改了等于没改 我改完前端逻辑,刷新页面却「没生效」。折腾半天才发现:服务端缓存(Memcached)只缓存数据数组,不缓存 HTML/JS;而浏览器会把整个页面(含内联 JS)缓存住。我加的 ?refresh=1 只清了服务端数据缓存,对浏览器缓存的旧 JS 完全无效。

解决办法:在 PHP 顶部加 no-store 系列响应头,强制浏览器每次重新拉页面:

header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');

header('Pragma: no-cache');

header('Expires: 0');

坑 2:ECharts tooltip 的隐藏 bug,让切换「失灵」 热力图加完三视图切换,点按钮「没反应」。控制台报 Cannot read properties of undefined (reading '1')

根因:热力图的 tooltip 用了 ...chartTheme.tooltip 展开,结果把默认 trigger:'axis' 继承了下来(heatmap 本该用 'item')。axis 触发时悬停传入的参数没有 .value,formatter 一读取就崩,还把 ECharts 实例状态搞坏,表现就是切换按钮失灵。

修法:热力图显式设 trigger:'item'、给 formatter 加空值保护、切换时用 notMerge:true 彻底清配置、渲染包 try/catch。

坑 3:海外 CDN 太慢,首屏空白 11 秒 最初 echarts 走 cdn.jsdelivr.net,国内加载 11 秒,打开页面长时间白屏。

修法:把 echarts.min.jsecharts-wordcloud.min.js 下载到本地、和 PHP 放一起,走自己的服务器(国内秒开),并保留 CDN 兜底;同时把库从 <head> 挪到图表脚本之前,避免阻塞首屏。

六、部署与安全

  • 上传时把 dashboard.phpchina-geo.jsonecharts.min.jsecharts-wordcloud.min.js 放同一目录。
  • 大屏直接放根目录会任何人可访问。我用了宝塔的防盗链(防 JS 被盗用)+ 流量限制(防被刷)+ IP 白名单(只有自己能开)来加固。
  • 服务器建议开启 .js 的 gzip,1MB 的 echarts 能压到 ~300KB,加载更快。

七、小结

从一个「想看看自己博客数据」的小念头,到做出一个能漂词云、能切视图、能看地图的单文件大屏,中间踩的坑比写的代码还多。但正是这些坑,让这个页面真正「可用」。

如果你也想给自己的 WordPress 做类似大屏,核心就三句话:直连数据库取数、ECharts 负责好看、缓存和防缓存(浏览器)决定体验

八、大屏文件

感兴趣的可以找我下载直接使用~

 

ts小陈

发表评论(不允许含有网址!)

:?: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :cry: :mrgreen: :neutral: :razz:

😀

已登录用户不需要填写以下内容