Tampermonkey脚本自动更新逻辑及页面重载时机问题咨询
Tampermonkey更新逻辑与自动重载解决方案
一、Tampermonkey的更新逻辑
你设置的6小时是最小检查间隔,Tampermonkey不会严格按这个时间点执行更新检查——为了避免大量脚本同时请求更新服务器,它会在设定周期基础上加入随机延迟,这就是实际更新时间经常超过7小时的原因。
除此之外,浏览器启动、Tampermonkey插件初始化、脚本所在页面加载时也会触发更新检查,但同样会附加随机延迟。只有当远程脚本的版本号(或最后修改时间)比本地脚本新时,才会下载替换本地文件,但替换完成后不会自动重载当前页面——因为脚本是在页面加载阶段注入的,已加载的页面不会自动重新注入新版本。
二、更新后自动重载的实现方式
Tampermonkey没有官方提供更新完成后的回调钩子,但可以通过以下两种可靠方式实现自动重载:
- 页面加载时的版本对比:每次页面加载时,对比本地存储的历史版本与当前
GM_info.script.version,如果不一致,说明脚本刚完成更新,此时可以直接重载页面(你当前代码里的informUserIfScriptUpdated函数已经具备这个逻辑的雏形)。 - 定时检查本地版本变化:当检测到远程有新版本后,启动一个定时任务,每隔一段时间检查本地脚本版本是否更新,一旦发现版本变化,立即重载页面。
三、更精准的更新时机处理方案
方案1:放弃预测,主动触发更新检查
既然随机延迟导致预测不准,不如主动请求远程脚本版本,发现更新后直接触发页面重载:
- 确保脚本的
@updateURL和@downloadURL配置正确; - 使用
GM_xmlhttpRequest请求远程脚本,从注释中提取@version字段; - 对比远程版本与本地
GM_info.script.version,如果远程版本更高,直接重载页面——Tampermonkey会在页面加载时自动完成更新并注入新版本。
方案2:优化现有预测逻辑
针对Tampermonkey的随机延迟,调整你的现有代码:
- 延长缓冲时间至90分钟,覆盖随机延迟的最大范围;
- 在预测的更新时间点之后,加入循环检查,直到检测到版本变化再重载页面。
修改后的核心代码示例:
function checkForUpdates() { getNewestScriptVersion().then((newestVersion) => { const actualScriptVersion = GM_info.script.version; if (actualScriptVersion >= newestVersion) return; // 存储待更新的版本号,用于后续检查 localStorage.setItem('pendingLatestVersion', newestVersion); const currentTimeInMs = Date.now(); const scriptLastUpdatedMs = GM_info.script.lastModified; const msSinceTheLastUpdate = currentTimeInMs - scriptLastUpdatedMs; const sixHoursInMs = 21600000; const ninetyMinutesBuffer = 5400000; // 改为90分钟缓冲 updateTimerSet = true; if (localStorage.getItem('updateAttempted')) { localStorage.removeItem('updateAttempted'); console.log('自动更新失败,可能更新周期设置超过6小时!停止检查。'); return; } const timeUntilUpdateIsAvailable = (sixHoursInMs - (msSinceTheLastUpdate % sixHoursInMs)) + ninetyMinutesBuffer; console.log('检测到新版本!预计更新时间:' + new Date(Date.now() + timeUntilUpdateIsAvailable)); setTimeout(() => { // 启动循环检查,每15分钟一次 const checkLoop = setInterval(() => { const currentLocalVersion = GM_info.script.version; if (currentLocalVersion === newestVersion) { clearInterval(checkLoop); localStorage.setItem('updateAttempted', true); localStorage.removeItem('pendingLatestVersion'); console.log('脚本已更新,正在重载页面...'); location.reload(); } }, 900000); // 15分钟间隔 }, timeUntilUpdateIsAvailable); }); }
方案3:独立辅助监听脚本
编写一个独立的Tampermonkey脚本,专门监听目标脚本的版本变化:
- 设置更高的检查频率(比如每小时一次);
- 通过
GM_info.scripts获取目标脚本的版本信息,对比历史版本; - 一旦发现版本更新,重载目标脚本所在的页面。
四、总结
- Tampermonkey的更新检查带有随机延迟,设置的最小周期仅为参考,实际更新时间会偏晚;
- 无官方更新回调,但可通过版本对比+定时检查实现自动重载;
- 最可靠的方式是主动检查远程版本,发现更新后触发页面重载,让Tampermonkey在页面加载时完成更新注入。
内容的提问来源于stack exchange,提问作者Dusan Milosevic
相关产品推荐
相关产品推荐

