向后/向前兼容导航定时-从时代转换为HR时间

时间:2019-06-17 00:24:53

标签: javascript timestamp unix-timestamp epoch navigation-timing-api

让我们从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级)以确认并声明:

  • 导航时序级别1使用unix epoch time,其余的使用...
  • 导航 2级计时使用 HR时间
  • 用户时间级别1使用 HR时间
  • 用户计时级别2使用 HR时间
  • 在Chrome和Firefox中,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

1 个答案:

答案 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不到毫秒)。