WP-Cron 不是操作系统里的定时任务,它是挂在页面请求上的:没有人来访问,就没有人去触发它。这不是实现细节的瑕疵,而是它与系统计划任务最根本的区别,也决定了它对首字节时间和稳定性的影响方式。想清楚这一点,再决定要不要改。
WP-Cron 靠什么被触发
机制很简单:WordPress 在处理页面请求的过程中,顺带检查有没有到点的任务,有就发起一次执行。没人访问站点(包括后台不登录、定时任务页面没人打开),到点的任务就继续排队等着,等到下一个访客到来才补跑。
这些任务的函数签名和参数可以在 WordPress 官方的函数与 API 代码参考里逐个查到;至于伪 cron 与系统计划任务官方更推荐哪一种,文档里没有给出结论。下面写的是机制层面的判断,不是官方推荐。
请求触发带来的三个副作用
- 首字节时间被搭进去:任务执行会占用这次请求的服务器资源。web.dev 的 Web Vitals 说明把 TTFB(首字节时间)列为辅助指标,并写明它的用途之一正是诊断 LCP 时遇到的"服务器响应慢"这类问题。把不属于访客请求的工作放进访客请求里,属于自己给自己加延迟。
- 时机不可控:任务实际执行时间取决于谁先来访问。这意味着备份、清理、缓存重建这些动作的触发点是不可预期的,尖峰时段可能被一次批量任务撞上。
- 低流量站点几乎不跑:访问量小的时候,任务可能积压很久才跑一次。定时发布、定期备份这类依赖它的功能,在低流量站点上表现最不稳定。
反过来说也有它的道理:它不需要服务器权限,迁移主机时不用重配。是否值得改,取决于你的任务量和流量结构。
换成系统计划任务,以及逐项核对的清单
做法本身不复杂:让站点不再靠访问触发,改由服务器的计划任务按固定间隔调用。切换时要逐项核对下面这些,漏一项就可能让功能静默失效。
- 先列出你现在依赖定时任务的功能:定时发布、定期备份、缓存重建、清理计划、邮件通知、库存同步。清单比想象的长,先列完再动手。
- 在关闭请求触发之前,确认服务器计划任务已经能正常执行并写入执行日志。没有日志的定时任务等于没有定时任务。
- 间隔设成比你最短的那个任务周期更密,靠计划任务反复检查到期情况,而不是为每个任务单独建一条;这样漏跑一次不会造成永久性延误。
- 手动强制执行一次全部到期任务,确认输出正常、耗时可接受。如果一次跑完要很久,说明任务本身需要拆分或错峰。
- 验证功能而不是验证进程:定时发布一篇测试内容、触发一次备份、确认邮件能发出。
- 保留关闭前后的任务执行记录各一份,事后核对没有任务被漏掉或重复执行。
- 把这一项写进运维清单:以后换主机、迁移站点或恢复备份时,都要重新确认计划任务还在。
为什么值得这么做,方向上与 web.dev 讲最有效的优化做法那篇一致:它把"就近分发加缓存"列为降低首字节时间的主要手段,核心思路是让重复请求不必每次都从头算。定时任务属于同一类问题——从"顺手做"改成"按点做"。
什么时候保持现状更合适
四种情况建议不动。一是站点几乎没有访问量,任务本来就没有积压压力。二是任务总量很小(比如只有一个每周备份),收益抵不过配置与维护成本。三是主机不给计划任务权限,或者只能在受限的共享环境里操作,强行改造容易变成长期维护负担。四是你还没有一份可靠的任务清单——在不知道有哪些任务的情况下关闭请求触发,等于在关一个你还不知道装了什么的东西。
另外提醒一句:改成系统计划任务解决的是"什么时候跑",不解决"跑得慢不慢"。如果某几个任务本身耗时很长,那是另一个问题,混在一起改会让两件事都说不清。相关数据的处理顺序可以看缓存、数据库与前端文件的按需优化,服务器与插件的分工见加速先选插件还是调服务器。
怎么确认任务真的按点跑了
看三样东西,缺一不可。一是计划任务自己的日志,确认它在固定间隔上真的被调起,而不是偶尔成功一次;二是任务的执行记录,确认每个任务的"上次运行时间"在稳定推进,而不是停在某个旧日期;三是功能侧的实际结果,定时内容按预期出现、备份文件在预期时间点生成、通知邮件按时到达。
顺手做一次反向验证:故意让一个任务到期,观察它在没有访客访问的时段是否仍然按点执行。这一步能直接证明改造真的生效,而不是恰好有访客帮它触发了。表现侧再按 URL 分组看一次状态变化,确认移动与桌面两端一致;web.dev 的口径说明里核心网页指标只有 LCP、INP、CLS 三项,这是建议性的体验目标,官方没有公布它与搜索排名的换算关系。
