为何调用PerformanceNavigationTiming获取页面加载时间返回0?
取值为0的核心原因
该异常通常由两类问题触发,按出现概率排序:
- 读取时序错误
PerformanceNavigationTiming.loadEventEnd的时间戳,会在当前页面所有绑定在window上的load事件回调全部执行完成后才会被浏览器写入。你在load事件的回调函数中同步读取该值时,load流程尚未完全结束,字段还未完成赋值,因此读取到初始值0,依赖loadEventEnd - startTime计算的duration字段自然也返回0。
你代码中判断document.readyState === 'complete'就同步执行读取的逻辑存在相同问题:document.readyState变为complete的触发时机早于所有load回调执行完成的节点,同步读取依然无法拿到最终值。 - 跨域安全策略限制
如果页面通过跨域跳转打开,且目标导航页面没有配置Timing-Allow-Origin响应头、未授权当前源读取其性能数据,浏览器会将该导航条目下所有时间相关字段统一置为0,避免跨域泄露页面加载的敏感信息。
修复方法
针对时序问题,只需要把读取逻辑放到当前同步执行队列的末尾,等待整个load流程走完后再读取即可,最简便的实现是给读取逻辑套一层0延迟的setTimeout,将其推到宏任务队列等待执行,也可以使用requestIdleCallback在浏览器空闲时读取:
export const useReportPageLoadTime = () => { useEffect(() => { const reportTime = () => { setTimeout(() => { const navPerformance = window.performance.getEntriesByType('navigation')[0] console.log({ duration: navPerformance.duration, blob: navPerformance.toJSON() }) }, 0) } if (document.readyState === 'complete') { reportTime() return } window.addEventListener('load', reportTime) return () => window.removeEventListener('load', reportTime) }, []) }
如果调整时序后依然读取到全0值,需要排查跨域限制问题:跨域场景下需要在导航目标页面的服务端配置Timing-Allow-Origin响应头,将当前上报数据的源加入允许列表,即可正常读取完整性能指标。
内容的提问来源于stack exchange,提问作者fraxture
相关产品推荐
相关产品推荐

