Files
wordpress-theme-aksrt/.zcode/plans/plan-sess_9dedb041-3430-4063-9835-8825229111bc.md
T

2.7 KiB

目标

把"点关注"从同步跑完整结算链(积分+勋章×3遍+等级,约几十条 SQL)优化为:接口只写关注表立即返回,结算在响应送达客户端之后执行。

改动内容(3 个文件)

1. src/User/Metrics.php — 删除冗余订阅

on_user_followed()(Metrics.php:93-98)只做 reevaluate_medals(following_id),而 BadgeAutoAward::on_follow 已经评估过该用户——这是同一请求内的第 3 遍重复评估。删除该方法和它的 add_action 注册(Metrics.php:34)。reevaluate_medals 方法本身保留(点赞/浏览等其他钩子仍在用)。

2. src/User/BadgeAutoAward.php — 删除对"关注者"的无效评估

on_follow()(BadgeAutoAward.php:61-68)同时评估关注者和被关注者,但 Badges::metric_value 的全部指标分支(registration_time/checkin/new_post/comment/followed(被关注数)/like/views/pay_income/pay_rebate)没有任何一个依赖"关注了多少人"——关注者评估必然零产出。改为只评估 $following_id(保留双参数签名以兼容钩子,unset($follower_id))。

3. src/User/Follow.php — 结算钩子延迟到响应之后

follow() 里的 do_action('aksrt_user_followed', ...)(Follow.php:50)改为经 register_shutdown_function 延迟执行:关闭回调里先调 fastcgi_finish_request()(PHP-FPM 下存在)把响应立即送达客户端,再触发钩子跑积分/勋章/等级结算。新增一个 private static function defer_action(string $hook, int ...$args) 辅助方法。

  • 非-FPM 环境(无 fastcgi_finish_request):退化为 shutdown 时机同步执行,行为与现状等价,无回归。
  • 不用 wp_schedule_single_event:WP-Cron 粒度不可控(禁用循环回执的站点要等系统 cron,积分勋章到账会延迟数分钟),shutdown 方案在所有环境都能即时结算。
  • aksrt_user_followed 仅 Follow.php:50 一处触发,4 个订阅者全部按传入 ID 工作、不依赖请求上下文,延迟执行安全。
  • 效果:关注接口响应路径只剩 WP REST 启动 + 1 次 SELECT + 1 次 INSERT + 1 次 COUNT(全部命中索引),勋章评估从 3 遍降为 1 遍且不再阻塞响应。

不在本次范围

前端乐观更新(点击瞬间翻转按钮、失败回滚)——上轮标注为可选项,用户未明确要求;异步化后反馈延迟已大幅下降,且与全站点赞/收藏的交互模式保持一致。需要可后续单独做。

验证

  • php -l 检查 3 个改动文件。
  • 浏览器实测:关注点击后按钮/Toast 应明显变快(仅剩接口往返);稍后刷新可见积分/勋章/等级照常到账(结算仍在同一请求生命周期内完成,只是后置)。
  • 取消关注路径不受影响(本就无钩子)。

提交

单条提交:perf(user): 关注结算异步化并去除冗余勋章评估。