performance.now()与Date.now()的区别

128

performance.now()Date.now()之间有什么区别?

考虑到performance.now()更为一致和独立,我是否应该将其视为替代Date.now()的选项?


27
不行!Date.now()返回自1970年1月1日00:00:00 UTC以来经过的毫秒数,而performance.now()返回自“任意时期”以来经过的毫秒/微秒数。基本上,只有在想要测量两个时间点之间的相对距离而不是它们在时间轴上的“绝对”位置时才应使用performance.now() - user703016
3
@buttifulbuttefly所说的,再加上 performance.now提供更精确的时间测量(精度可达毫秒以下级别)。 - markE
5
确实,需要更精确的“时间测量”,而不是更精确的“时间”。 - Amadan
4
这不再是真的了。由于Spectre攻击performance.now的精度受到了限制 - zypA13510
比较:Date.now() vs Date.getTime() - KyleMit
3个回答

111

它们两个服务于不同的目的。

performance.now()与页面加载相关,精确度更高。使用场景包括基准测试以及需要高分辨率时间的媒体(游戏、音频、视频等)。

需要注意的是,performance.now()仅在新版浏览器中可用(包括IE10+)。

Date.now()与Unix纪元(1970-01-01T00: 00: 00Z)有关,并依赖于系统时钟。使用场景包括JavaScript自始至终一直存在的日期处理。

有关详细信息,请参见:当毫秒不够用:performance.nownow方法(Internet Explorer) - MSDN

官方W3C规范可以在此处找到:高分辨率时间API


12
这种精度是有代价的。速度会慢50%。如果你需要在紧密循环中使用它,那么这一点需要注意。https://jsperf.com/perf-vs-date/1 - Eyal
3
抱歉,我想说的是速度要慢80%。 :-( - Eyal
5
请记住谷歌审核对于 date.now() 的看法。https://developers.google.com/web/tools/lighthouse/audits/date-now - StLia
4
目前在Firefox中,performance.now()的速度比其他浏览器快大约20%,但是令人惊讶的是,在其他浏览器中速度却慢了60%。你可以自己检查一下:https://jsbench.me/s6jz9v29i3/1 - Picard
24
为什么developers.google.com/web/tools/lighthouse/audits/date-now会重定向到这个stackoverflow问题? - Muhammad Umer
显示剩余4条评论

31

Date.now() 返回自1970年1月1日00:00:00 UTC起经过的毫秒数,performance.now() 返回毫秒数,其中微秒位于小数部分,从文档导航的开始performance.timing.navigationStartperformance.now() 调用。 另一个重要的区别是Date.now()performance.now() 之间的差异是后者单调递增的,因此两个调用之间的差异永远不会是负数。

为了更好地理解,请访问链接


11
我注意到的第一件事是,performance.now()Date.now()4倍(在我的电脑上是40万次操作对比10万次)。然而,如果你想要准确的计时/自页面加载以来的时间,使用performance.now()是更好的选择。它完全依赖于代码开始运行的时间,时钟的变化不会影响时间。它也更准确:计算的是毫秒的十分之一而不是整毫秒。 简而言之 在非Firefox浏览器上,Date.now()精确到~1msperformance.now()精确到~0.1ms,除非在某些情况下。如果你使用Firefox,两者的精确度都降低到2ms。它们都非常快速。 支持和速度 就支持而言,Date.now()performance.now()稍微更受支持,因为两者都受到现代浏览器的支持,甚至包括Internet Explorer 10和11

new Date().getTime()只是有一点点支持,并且比Date.now()2倍。它慢是因为它创建了一个大对象,但只调用了一个函数。

然而,这个caniuse.com页面显示performance.now()几乎总是可以使用,在98.25%的情况下(截至目前)。

(从这里开始,我只会提到Date.now(),但在下面的情况中new Date.getTime()是一样的)

用法

Date.now()可以(而且应该)用于计算时间差(特别是requestAnimationFrame():它可以轻松获取在120fps显示器上的正确帧!它也可以用作时钟。它计算自Unix纪元以来经过了多少毫秒(有关更多详细信息,请参见顶部答案)。

一个特别有趣的用例是在一帧中多次调用Date.now(),以便在经过一定时间后停止计算。由于Date.now()非常快,这应该不是什么问题。

对于需要更高精度的应用程序(见下文),可以使用performance.now()。如果您正在使用计时器(因为它仍然以毫秒计数),它的行为与Date.now()完全相同,只是更准确。
要将performance.now()用作(通常)更准确的Date.now()或对象,请将performance.timing.navigationStart添加到值中。这似乎与Date.now()对象相差几毫秒,但我不确定原因。只是不要将两者结合使用。
准确性
从我所了解的情况来看,在我的Chrome桌面上,performance.now()相对于Date.now()只是准确性提高了10倍:考虑到0.1毫秒的时间跳跃。然而,这种准确性对于大多数时间敏感的应用程序来说已经足够好了(请阅读Firefox部分以了解更多关于它们准确性的信息)。它可能看起来更准确(例如313015.59999999404),但实际上并不是这样的:出于安全原因,它被有意限制了,因为时间的利用可能会允许恶意代码访问其他应用程序。如果你不想以这种丑陋的方式显示它,你可以使用performance.now().toFixed(1)使其更准确。你也可以通过在开头添加一个加号将其转换为Number类型:+performance.now().toFixed(1)应该可以工作。 Firefox 很遗憾,如果您的用户使用的是Firefox并且没有访问跨域头信息,那么这个性能(0.1毫秒)是不可能实现的。相反,您只能获得2毫秒的准确度(与Date.now()相同!)为了启用它,请在您的文档中添加Cross-Origin-Opener-Policy: same-origin和Cross-Origin-Embedder-Policy: require-corp。用户还可以将此速度提高到100毫秒(或更高)。请访问Mozilla文档以获取更多信息。

3
这不是浮点数问题,现在故意限制精度以减轻Spectre和其他问题的影响。 - pfg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接