Google reCAPTCHA v3首次请求后获取token耗时剧增问题排查
Google reCAPTCHA v3 重复调用性能异常问题排查
我在Web应用中使用Google reCAPTCHA v3,实现了runCaptcha函数通过grecaptcha.execute获取token,但首次调用后,每次获取新token的耗时剧增且维持高位。
耗时测量数据
首次测试
- 第1次调用:reCaptcha time: 888.7578125 ms(符合预期)
- 第2次调用:reCaptcha time: 15654.778076171875 ms
- 第3次调用:reCaptcha time: 15729.93408203125 ms
- 第4次调用:reCaptcha time: 15709.18603515625 ms
- 第5次调用:reCaptcha time: 15377.43505859375 ms
第二次测试
- 第1次调用:reCaptcha time: 787.9111328125 ms(符合预期)
- 第2次调用:reCaptcha time: 15916.755126953125 ms
- 第3次调用:reCaptcha time: 15067.10205078125 ms
- 第4次调用:reCaptcha time: 15615.06201171875 ms
- 第5次调用:reCaptcha time: 15400.135986328125 ms
- 第6次调用:reCaptcha time: 15716.2509765625 ms
- 第7次调用:reCaptcha time: 15990.376953125 ms
- 第8次调用:reCaptcha time: 15700.85205078125 ms
相关实现代码
export function runCaptcha(siteKey, captchaAction) { return new Promise((resolve, reject) => { if (typeof grecaptcha === 'undefined') { reject('grecaptcha is not defined'); return; } grecaptcha.ready(function () { grecaptcha.execute(siteKey, { action: captchaAction }).then(function (token) { resolve(token); }).catch(function (error) { reject('Failed to execute reCAPTCHA: ' + error); }); }); }); }; document.getElementById('submitButton').addEventListener('click', function (event) { console.time('reCaptcha time'); if (siteKey && siteKey.value.length > 0 && action && action.value.length > 0) { runCaptcha(siteKey.value, action.value) .then(token => { document.getElementById('txtCaptchaToken').value = token; console.timeEnd('reCaptcha time'); if (form != null) form.requestSubmit(); }); } });
咨询问题
- 为何首次请求后获取token耗时剧增且保持稳定?
- 是否在grecaptcha初始化或实例管理上存在问题?
grecaptcha.execute是否存在已知性能问题?
问题解答
1. 首次请求后耗时剧增的核心原因
reCAPTCHA v3的token默认有效期为2分钟,Google后端针对重复请求设置了反滥用限流机制:当短时间内重复调用execute获取同一action的token时,第二次及之后的请求会被强制延迟约15秒返回,这是官方为防止恶意脚本批量获取token的策略。你的测试数据中第二次开始的耗时稳定在15秒左右,完全符合该延迟特征。
2. 初始化与实例管理的问题排查
你的代码没有明显的初始化错误,但有可优化点:grecaptcha.ready()只需要在页面加载时执行一次,无需每次调用runCaptcha都重复触发。不过这个重复调用并非导致性能问题的直接原因,核心还是官方的限流机制在起作用。
另外需确认:reCAPTCHA的SDK是否只加载了一次?若页面重复引入SDK可能导致实例冲突,但从你的耗时数据来看,更符合官方限流而非实例问题。
3. grecaptcha.execute的已知性能问题
官方本身不存在通用性能问题,但以下场景会导致异常耗时:
- 反滥用限流:短时间重复调用同一action触发15秒延迟,这是你遇到的情况;
- 网络环境问题:用户网络到Google服务器链路不稳定会导致请求超时或延迟,但你的数据稳定在15秒,可排除该可能;
- 页面资源阻塞:页面大量同步脚本阻塞事件循环会延迟
grecaptcha.execute回调执行,但你的首次调用正常、后续稳定延迟,不符合该情况。
优化建议
- 避免短时间内重复调用
execute,应在表单提交前提前1-2分钟获取token,或在token过期后再重新获取; - 缓存已获取的token,在有效期内直接复用,减少重复请求;
- 将
grecaptcha.ready()初始化逻辑移到页面加载完成时执行一次,后续调用execute直接使用初始化后的实例:
// 页面加载时提前初始化reCAPTCHA就绪状态 let captchaReady = false; if (typeof grecaptcha !== 'undefined') { grecaptcha.ready(() => { captchaReady = true; }); } export function runCaptcha(siteKey, captchaAction) { return new Promise((resolve, reject) => { if (typeof grecaptcha === 'undefined') { reject('grecaptcha is not defined'); return; } const execute = () => { grecaptcha.execute(siteKey, { action: captchaAction }) .then(resolve) .catch(error => reject('Failed to execute reCAPTCHA: ' + error)); }; captchaReady ? execute() : grecaptcha.ready(execute); }); };
内容的提问来源于stack exchange,提问作者Denis Campara
相关产品推荐
相关产品推荐

