需配置timing-allow-origin响应头以启用跨域静态资源性能监控,使前端能获取connectstart、duration等真实计时数据;nginx中通过add_header指令设置,支持单源、多源(空格分隔)或通配符(*),但带凭据请求须指定具体源。

要通过 Timing-Allow-Origin 响应头开启静态资源(如 JS、CSS、图片、字体等)的性能监控,核心是让前端 JavaScript 能够访问到跨域资源的完整 PerformanceResourceTiming 数据,尤其是 duration、connectStart、fetchStart 等关键字段。默认情况下,浏览器会屏蔽跨域资源的详细计时信息(只保留 redirectStart、redirectEnd、duration 且常为 0),而 Timing-Allow-Origin 正是解除这一限制的标准化响应头。
为什么需要 Timing-Allow-Origin?
当页面从 CDN 或独立静态资源域名(如 static.example.com)加载脚本或图片时,该请求属于跨域请求。出于安全考虑,浏览器会“模糊化”其 Performance API 中的计时字段——即使你调用 performance.getEntriesByType('resource'),返回的条目中多数时间戳为 0 或 undefined。只有服务端明确声明允许共享计时数据,浏览器才会暴露真实耗时。
这个机制和 Access-Control-Allow-Origin 类似,但专用于性能时序数据,不涉及内容读取权限。
如何正确配置 add_header Timing-Allow-Origin
在 Web 服务器(如 Nginx)中,对静态资源响应添加该头即可。注意:它必须出现在实际返回静态文件的响应中,而非 HTML 页面本身。
-
允许特定源:例如只允许
https://app.example.com获取计时数据add_header Timing-Allow-Origin "https://app.example.com"; -
允许多个源:用空格分隔(不是逗号)
add_header Timing-Allow-Origin "https://app.example.com https://staging.example.com"; -
允许所有源(谨慎使用):
add_header Timing-Allow-Origin "*";
⚠️ 注意:*不适用于带凭据(credentials)的请求(如含 Cookie)。若资源请求设置了credentials: 'include',则必须指定具体源,不能用通配符。
配合前端代码采集真实资源耗时
服务端配置生效后,前端需在资源加载完成后主动采集数据。推荐在页面加载完成(load 事件)或使用 PerformanceObserver 监听:
- 确保资源是通过标准方式加载(
<script src></script>、<link rel="stylesheet">、new Image()等),非 XHR/fetch(后者走PerformanceEntry.entryType === 'navigation'或'resource',但需额外处理 CORS) - 示例:获取某个 JS 文件的完整加载耗时
const entries = performance.getEntriesByType('resource');<br>const myJs = entries.find(e => e.name.includes('main.js'));<br>if (myJs) console.log('load time:', myJs.duration); // 此时 duration 不再是 0 - 建议用
PerformanceObserver实时监听新资源,避免漏采动态插入的资源(如懒加载图片、异步组件 JS)
验证是否生效
最直接的方法是打开 Chrome DevTools → Network 面板 → 找一个跨域静态资源 → 查看 Response Headers 中是否存在 Timing-Allow-Origin;然后在 Console 中运行:
performance.getEntriesByType('resource').filter(r => r.initiatorType === 'script')[0]
检查输出对象中的 connectStart、responseEnd 等字段是否为有效数字(非 0 或 NaN)。若仍为 0,常见原因有:
– 头未正确添加到该资源响应(检查 Nginx location 匹配是否准确)
– 浏览器缓存了旧响应(尝试硬刷新或禁用缓存)
– 源不匹配(比如前端从 http://localhost:3000 访问,但头只写了 https://app.example.com)










