让我们从www.w3.org的笔记中进行介绍,其中包括两个要比较的重要链接。
PerformanceTiming接口在[NAVIGATION-TIMING]中定义,并且 现在被认为已过时。名称的使用 支持PerformanceTiming接口以保持向后 兼容,但没有计划将此功能扩展到 PerformanceNavigationTiming接口中定义的名称 将来[NAVIGATION-TIMING-2](或其他界面)。
我已经制作了一个函数,该函数应该向后和向前兼容,因为我们正处于转换到2级的中间时代。因此,此函数从事件名称获取时间< / em>在Chrome上有效,但在Firefox中不可用:
function nav(eventName) {
var lev1 = performance.timing; //deprecated unix epoch time in ms since 1970
var lev2 = performance.getEntriesByType("navigation")[0]; //ms since page started to load. (since performance.timing.navigationStart)
var nav = lev2 || lev1; //if lev2 is undefined then use lev1
return nav[eventName]
}
说明:当没有“ navigation”条目时,这会退回到基于自1970年以来以毫秒为单位的 Unix epoch time时间(lev1)(lev1)进行导航计时的方法,而新的自从当前文档导航开始加载以来,方式(lev2)是 HR time以毫秒为单位,这与始终具有HR时间格式的User Timing一起使用非常有用。
在所有情况下如何获取函数返回HR时间?
当我看到一个数字超过10个数字且没有句点时,我知道这是从不建议使用的Navigation Timing级别1获得的时间。所有其他测试用例都给出小数点数字,这意味着它是HR精度更高的时间。最大的问题是它们的 time origin 不同。
我经历了困惑,试用错误和沮丧的查询(MDN尚未更新为2级)以确认并声明:
performance.now()
也具有 HR时间。如何将unix epoch time转换为HR time?
已解决。:
该代码已在Amadan的帮助下更正。
查看已接受答案中的评论。
function nav(eventName, fallback) {
var lev1 = performance.timing; //deprecated unix epoch time in ms since 1970
var lev2 = performance.getEntriesByType("navigation")[0]; //ms since page started to load
var nav = lev2 || lev1; //if lev2 is undefined then use lev1
if (!nav[eventName] && fallback) eventName = fallback
// approximate t microseconds it takes to execute performance.now()
var i = 10000, t = performance.now()
while(--i) performance.now()
t = (performance.now() - t)/10000 // < 10 microseconds
var oldTime = new Date().getTime(),
newTime = performance.now(),
timeOrigin = performance.timeOrigin?
performance.timeOrigin:
oldTime - newTime - t; // approximate
return nav[eventName] - (lev2? 0: timeOrigin);
// return nav[eventName] - (lev2? 0: lev1.navigationStart); //alternative?
}
在使用旧时间 lev1 的情况下,performance.timeOrigin
会减少。
如果浏览器没有它,则通过将performance.now()
从timeOrigin 开始的时间从(new Date().getTime()) 从Unix Epoch 开始的时间减少到< strong> 从Unix时代开始的时间 。显然,这是定义,尽管链接对此含糊不清。我通过测试确认,并且相信答案。希望w3c对timeOrigin的定义比:性能测量开始时间的高分辨率时间戳。
函数返回的值表示自时间原点起经过的时间。
在大多数情况下,这可能无关紧要,但是执行t
所花费的测量时间performance.now()
被删除以近似同时执行。
我在自己的Raspberry Pi上测量到t
几乎达到10微秒,并且在各种循环大小下都相当稳定。但是我的Lenovo在测试更大的循环大小时,并没有那么精确地舍入小数并在t
上获得更短的时间。
另一种解决方案在代码的最后一行被注释掉了。
已弃用的performance.timing.navigationStart
:
代表距UNIX纪元以来的瞬间(以毫秒为单位) 卸载提示在上一个文档中的终止后 相同的浏览上下文。如果没有以前的文档,则此值 将与PerformanceTiming.fetchStart
相同
因此,要检查当前文档(忽略以前的文档),然后使用不推荐使用的performance.timing.fetchStart:
表示自UNIX时代以来的瞬间(以毫秒为单位), 浏览器已准备好使用HTTP请求来获取文档。这个 现在是检查所有应用程序缓存的时间之前。
如果已弃用的属性是浏览器唯一能理解的属性,那么使用它当然是正确的。当getEntriesByType
中没有定义“导航”时使用它,否则使用good browser support。
在return
之前,快速检查通过此行彼此确认:
console.log(performance.timeOrigin + '\n' + lev1.navigationStart + '\n' + lev1.fetchStart)
在我的Chrome中显示如下结果
1560807558225.1611
1560807558225
1560807558241
答案 0 :(得分:1)
仅当浏览器支持HR时间2时才有可能:
let unixTime = hrTime + performance.timeOrigin;
let hrTime = unixTime - performance.timeOrigin;
但是,performance
通常用于时间差异,而不必关心绝对时间戳的起源。
对于不支持HR time 2的浏览器,或者半心半意地“支持”该浏览器的浏览器,可以通过以下方式进行伪造:
const hrSyncPoint = performance.now();
const unixSyncPoint = new Date().getTime();
const timeOrigin = unixSyncPoint - hrSyncPoint;
它并不十分精确,但对于大多数用途来说应该足够好(在我的系统上,performance.timeOrigin - timeOrigin
不到毫秒)。