第三方统计脚本加载超时需手动设8秒硬超时,因onerror不触发“无声超时”;用settimeout+promise.race封装,超时即移除script元素并执行轻量降级(如空函数桩、beacon上报),避免document.write或重复加载。

第三方统计脚本加载超时怎么判断
浏览器不会主动告诉你 script 加载卡住了,onerror 只在明确失败(如 404、CORS 拒绝)时触发,对网络卡顿、DNS 慢、TCP 握手挂起等“无声超时”完全无感。必须自己设时限——不能依赖 load 或 error 事件兜底。
推荐 8 秒硬超时:短于 5 秒容易误判(尤其弱网),长于 12 秒用户已感知卡顿。超时后直接执行降级逻辑,不等事件回调。
- 用
setTimeout+Promise.race封装加载过程,避免手动维护状态标志 - 超时后立即移除未完成的
script元素,防止它后续突然加载成功又执行两次 - 不要用
document.write降级,会清空整个页面;改用console.warn记录或写入隐藏div
如何安全替换为备用统计脚本
降级不是“换一个 URL”,而是要避开原脚本的所有副作用:比如同步阻塞、document.write、修改全局变量、覆盖已有 SDK 实例。直接 src 切换风险极高。
真正可控的做法是:只加载最小骨架脚本(如一行 console.log 或空函数定义),再通过动态 fetch + eval(慎用)或预置函数桩模拟核心 API。
- 备用脚本应仅暴露
window.ga、window.sentry等同名对象,方法体为空或打点到localStorage - 若需上报,改用
navigator.sendBeacon发送轻量日志,不依赖第三方 SDK - 避免在降级路径里再次调用
document.createElement('script'),可能触发重复加载竞争
async 脚本和 defer 脚本的降级时机差异
async 脚本一旦下载完成就立刻执行,可能在 DOM 构建中途打断;defer 则排队等到 DOMContentLoaded 前执行。这意味着:超时降级逻辑必须在两者不同生命周期里插入。
对 async:降级检查要在 script 创建后立即启动,不能等 head 插入完成;对 defer:可延迟到 document.readyState === 'interactive' 后再启动计时器,避免误杀。
- 用
performance.now()记录脚本创建时间,超时计算基于该起点,而非页面开始加载时间 - 不要监听
document.addEventListener('DOMContentLoaded', ...)来触发降级检查——它本身可能被阻塞 - 多个统计脚本并存时,每个都应有独立超时控制,避免一个失败拖垮全部
CDN 故障时 fallback 到本地 minified 版本的坑
看似稳妥的“CDN 失败切本地”方案,实际常因路径、SRI(Subresource Integrity)、MIME 类型三重校验失败而二次崩溃。浏览器对本地 file:// 或内联 blob URL 的模块解析规则和 CDN 完全不同。
真正能落地的 fallback 是:提前把最小化统计桩(

