跳转至
本页初次创建于:2026年03月11日 11:52:51(UTC+8/GMT+8)
本页最后更新于:2026年06月03日 14:22:01(UTC+8/GMT+8) (若有显示错误请Ctrl+F5强制刷新页面,无效请群内反馈)

TCY 文档站性能优化设计(方案 A:低风险渐进)

  • 日期:2026-03-07
  • 范围:docs/javascripts/extra.jsdocs/javascripts/tcy-status-monitor.jsdocs/javascripts/random-sentence.jsdocs/javascripts/cursor.js
  • 目标:在不改变页面效果、交互行为、现有功能稳定性的前提下,降低切页后性能劣化与重复网络开销。

1. 背景与问题陈述

站点已开启 navigation.instant,页面切换属于 SPA 局部更新模型。此模式下若脚本按“整页刷新心智”书写,容易出现:

  1. 全局监听器重复绑定,切页次数越多越卡;
  2. 同一数据在短时间内重复请求(状态 API、语录 JSON);
  3. 常驻动画循环在空闲状态持续占用主线程。

这些问题不会立刻破坏功能,但会造成“越逛越重”的体验,尤其在移动端和低功耗设备上更明显。


2. 设计目标与非目标

2.1 目标

  • 保持 UI/交互视觉效果一致;
  • 保持功能行为一致(音乐、主题、目录、状态卡片、一言、粒子效果);
  • 降低重复事件监听与重复请求;
  • 降低空闲 CPU 占用;
  • 每一步可独立回滚。

2.2 非目标

  • 不重构页面架构;
  • 不改导航逻辑;
  • 不引入新依赖;
  • 不调整文案和设计语言。

3. 方案 A(低风险渐进)

A-1:页面级监听器生命周期治理(extra.js

现状document$.subscribe 每次切页都会调用 tcyInitPage(),而 tcyInitPage() 内部为拖拽 TOC 等能力注册了多个 document/window 监听器。元素会被删除,但监听器可能累积。

设计: - 引入页面级 AbortController(全局仅一个); - 每次 tcyInitPage() 开始先 abort 上一轮,再创建新 controller; - 将本轮绑定的 document/window/fab 监听器统一挂在 signal 上,实现自动清理。

为什么低风险: - 不改变监听函数逻辑,不改变触发条件,只改变“解绑时机”; - 删除旧页面节点前后都安全; - 与 instant 生命周期天然匹配。


A-2:状态 API 短 TTL 缓存(tcy-status-monitor.js

现状:进入包含状态面板的页面时,会对 19 个节点逐一请求;短时间切换页面会重复请求。

设计: - 增加内存缓存(挂在 window),结构:{ ts, data: { address: onlineBool } }; - TTL 默认 60 秒; - 若缓存未过期,直接使用缓存结果;过期再请求并更新缓存。

为什么低风险: - 渲染结构不变、文案不变; - 仅减少重复请求,不改变离线/在线判定逻辑; - TTL 短,不影响状态新鲜度。


A-3:一言 JSON Promise 缓存(random-sentence.js

现状:每次页面订阅回调都会 fetch('/assets/data/hitokoto_bundle.json')

设计: - 缓存“数据 Promise”到 window 全局; - 首次发请求,后续复用同一 Promise; - 每次仍随机抽取一句,保证体验一致。

为什么低风险: - UI 输出逻辑不变; - 错误 fallback 保留; - 只减少网络与 JSON 解析开销。


A-4:粒子动画按需帧循环(cursor.js

现状requestAnimationFrame 常驻循环,即使没有粒子也持续运行。

设计: - 改为“有粒子才跑”:粒子数组为空时停止 rAF; - 鼠标移动/点击产生粒子时自动唤醒; - 页面隐藏时暂停,恢复可自动继续。

为什么低风险: - 粒子生成、更新公式与样式不变; - 只是空闲时不再空转; - 视觉表现一致。


4. 实施顺序与回滚点

  1. extra.js(监听器生命周期)
  2. tcy-status-monitor.js(TTL 缓存)
  3. random-sentence.js(Promise 缓存)
  4. cursor.js(按需 rAF)

每完成一步执行回归;若异常,回滚该文件即可,不影响其它步。


5. 验证计划(必须)

功能回归

  • 切换 10+ 次页面后:
  • TOC 浮窗可开关、可拖拽、点击外部可关闭;
  • 音乐播放器仍可播放/拖动/换曲;
  • 状态卡片仍显示在线/离线;
  • 一言正常显示;
  • 光标粒子视觉一致。

性能观察

  • DevTools Performance/Memory:
  • 多次切页后监听器数量不再线性增加;
  • Network 中状态 API 与 hitokoto JSON 重复请求显著下降;
  • 空闲 CPU 占用下降(粒子空闲状态)。

6. 风险与控制

  • 风险:事件绑定方式调整导致个别交互失效。
  • 控制:仅改绑定生命周期,不改业务处理函数;按模块回归。
  • 风险:缓存导致数据短时不更新。
  • 控制:TTL 60 秒,过期自动刷新。
  • 风险:rAF 停启边界导致粒子“偶发不动”。
  • 控制:新增粒子时显式唤醒循环,加入可见性处理。

7. 预期收益

  • 切页后性能劣化显著减轻;
  • 重复请求减少,网络与 API 压力下降;
  • 空闲主线程占用下降;
  • 在不改视觉/交互前提下提升整体流畅度与稳定性。
加入服务器
†01 TCYMC WEB / EST.2025