如何使用JavaScript正确获取页面加载时长,解决load事件返回0问题
页面加载总耗时获取问题解答
问题根因
你在window.load事件回调中直接读取performance.getEntriesByType("navigation")[0].duration返回0,是因为Navigation Timing API的duration属性需要等整个页面导航流程全部完成、包括load事件的所有同步回调执行完毕后,才会被浏览器写入最终的计算值。load事件触发时,当前回调还在执行栈中,浏览器尚未完成耗时统计的最终赋值,因此读取结果为0。
更规范的替代方案
不需要用setTimeout hack,你可以直接使用pageshow事件,该事件会在load事件完全执行结束后触发,此时可直接读取到正确的耗时数据:
window.addEventListener("pageshow", function(){ console.log(performance.getEntriesByType("navigation")[0].duration); });
补充说明
- 你用到的
setTimeout(fn, 0)写法生效的原因是:setTimeout回调会被推入宏任务队列,需要等当前load事件的同步执行栈清空后才会执行,此时浏览器已经完成了duration的赋值,因此可以读到正确结果,属于非规范的兼容写法,优先推荐使用pageshow事件。 - 如果需要获取更多细分加载指标,可以直接从
PerformanceNavigationTiming实例中读取对应属性计算:
window.addEventListener("pageshow", function(){ const navTiming = performance.getEntriesByType("navigation")[0]; // DNS查询耗时 const dnsTime = navTiming.domainLookupEnd - navTiming.domainLookupStart; // TCP连接耗时 const tcpTime = navTiming.connectEnd - navTiming.connectStart; // 首字节响应耗时 const ttfb = navTiming.responseStart - navTiming.requestStart; // 总加载耗时 const totalTime = navTiming.duration; });
- 若页面是从后退缓存(bfcache)加载的,
pageshow事件的persisted属性会为true,此时获取的duration是缓存页对应的耗时,如有需要可单独做分支处理。
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

