哪些是准确测量页面加载时间的正确指标?

Rou*_*ica 4 javascript load-time page-load-time firefox-developer-tools

我正在使用 JavaScript Performance API,并且试图找出正确的指标组合,以便在请求和加载任何单个页面时在控制台上记录页面加载时间。

TLDR: 我想使用 JavaScript 的性能 API来获取接近Firefox 开发人员工具(或任何浏览器开发人员工具)的“网络”选项卡load上报告的数字的数字。

请参阅下图中右侧的数字:

Firefox 开发者工具性能指标

我不会有任何问题,但事实上,我尝试过的组合都无法始终接近loadFirefox 开发者工具的“网络”选项卡上报告的数字 - 有时我得到的最终数字高达百分之几第二次下,有时相同的量超过。

也许我已经达到了尽可能接近的数字,但我想确保我做到了,并且不会意外地引用不适当的指标。

以下是我正在使用的指标(来自PerformanceNavigationTiming的界面Performance API):

  • domainLookupEnd
  • connectEnd- 我以前用过这个,但现在没有
  • responseEnd
  • loadEventStart

这就是我目前所拥有的:

window.addEventListener('load', () => {
  
  let domainLookupEnd = performance.getEntriesByType('navigation')[0].domainLookupEnd;
  let connectEnd = performance.getEntriesByType('navigation')[0].connectEnd;
  let responseEnd = performance.getEntriesByType('navigation')[0].responseEnd;
  let loadEventStart = performance.getEntriesByType('navigation')[0].loadEventStart;
 
  console.log(`
domainLookupEnd: ${domainLookupEnd}
connectEnd: ${connectEnd}
responseEnd: ${responseEnd}
loadEventStart: ${loadEventStart}

Page loaded in: (${responseEnd} - ${domainLookupEnd})
Page built in: (${loadEventStart} - ${responseEnd})
Page loaded and built in: (${loadEventStart} - ${domainLookupEnd})

// ^^^ All this is just temporary helper info to ensure that the three lines below are correct 

Page loaded in: ${((responseEnd - domainLookupEnd) / 1000)} seconds.
Page built in: ${((loadEventStart - responseEnd) / 1000)} seconds.
Page loaded and built in: ${((loadEventStart - domainLookupEnd) / 1000)} seconds.
  `);
});
Run Code Online (Sandbox Code Playgroud)

我相当一致地发现 JavaScript 控制台中报告的指标比“网络”选项卡报告的时间少千分之一 ( 0.001) 到(多达)百分之四 ( 0.04) 秒。load

这是我能期望的最好结果,还是我做错了什么/选择了错误的指标?

vas*_*vas 8

您的时间可能会更快,因为您测量的量更少

让我们从 MDN 的“衡量性能”中非常出色的说明开始:

导航计时 API 可以处理的各种处理程序,包括 导航计时 API 指标 卸载提示 重定向 卸载 应用程序缓存 DNS TCP 请求响应处理 onLoad navigationStart redirectStart redirectEnd fetchStart domainLookupEnd domainLookupStart connectStart (secureConnectionStart) connectEnd requestStart responseStart responseEnd unloadStart unloadEnd domInteractive domContentLoaded domComplete loadEventStart loadEventEnd

您包含的最早的段时刻是,这意味着仅在图中绿色 DNS 查找之后的domainLookupEnd内容。

MDN 和 Mozilla 包括更多

下面的所有 MDN 和 Mozilla 文档都考虑navigationStart页面加载时间测量的开始,如果不是的话,至少转到。loadEventStartloadEventEnd

MDN 的页面加载时间文档说:

页面加载时间是加载页面所需的时间,从导航开始加载事件开始测量。

let time = performance.timing;

let pageloadtime = time.loadEventStart - time.navigationStart;
Run Code Online (Sandbox Code Playgroud)

MDN 的导航计时 API文档对页面加载时间的计算略有不同:

计算页面总加载时间

要计算加载页面所花费的总时间,您可以使用以下代码:

const perfData = window.performance.timing;
const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
Run Code Online (Sandbox Code Playgroud)

这会从加载事件处理程序返回的时间 (loadEventEnd) 中减去导航开始的时间 (navigationStart)。这为您提供了感知的页面加载时间。

Mozilla 的改进 Firefox 页面加载(2020) 博客文章:

我们将页面加载定义为单击链接或在 URL 栏中按 Enter 键到页面显示在浏览器中并可供使用之间的时间。

Mozilla 的比较浏览器页面加载时间:方法论简介(2017) 似乎与以下内容相符loadEventEnd

loadEventEnd表示请求页面的加载事件完成的时刻,即页面的所有静态内容完全加载。

这是一个合理的担忧,但loadEventEnd可能不是衡量用户加载页面时在屏幕上体验的最佳指标。然而,loadEventEnd最近发现平均会话加载时间可以很好地预测用户跳出率。

您也可能正在测量缓存命中而不是新的网络请求

Firefox 开发者工具分别显示两者,因此您应该确保您使用的数字集与代码请求的处理方式相匹配。

如何将该onLoad段包含在您的测量中

如果 Firefox 在其测量中包括整个段,则它包括所有脚本或事件脚本onLoad的执行时间。目前,这包括您自己的测量脚本的执行时间!onLoadload

这可能可以解释为什么有时它的差异如此之小(“千分之一”),有时则相差更多(“百分之四”):在测量脚本是唯一onLoad脚本的页面上,它的差异仅在于执行该脚本所需的时间,并且在脚本越多的页面上,花费的时间越多,测量的差异也越大。

所有脚本完成没有标准事件触发执行。onLoad因此,您必须稍后从内部安排它onLoad

let time = performance.timing;

let pageloadtime = time.loadEventStart - time.navigationStart;
Run Code Online (Sandbox Code Playgroud)

其他有用的资源

衡量 2022 年 Web 性能:权威指南