Performance.now()
performance.now()
方法返回一个精确到毫秒的 DOMHighResTimeStamp
。
这个时间戳实际上并不是高精度的。为了降低像Spectre这样的安全威胁,各类浏览器对该类型的值做了不同程度上的四舍五入处理。(Firefox从Firefox 59开始四舍五入到2毫秒精度)一些浏览器还可能对这个值作稍微的随机化处理。这个值的精度在未来的版本中可能会再次改善;浏览器开发者还在调查这些时间测定攻击和如何更好的缓解这些攻击。
Note: 此特性在 Web Worker 中可用
返回值表示为从time origin之后到当前调用时经过的时间
牢记如下几点:
- 在以
Window
上下文创建各个worker中,performance.now()
的值要比在创建这些worker的window中的小。它原来等于main上下文的t0
,但是现在不是了。 - 在共享worker或服务worker中,在worker中的值可能要比main上下文中高,因为window对象可能在这些worker之后创建。
语法
const t = window.performance.now();
示例
const t0 = window.performance.now();
doSomething();
const t1 = window.performance.now();
console.log("doSomething函数执行了" + (t1 - t0) + "毫秒.")
和JavaScript中其他可用的时间类函数(比如Date.now
)不同的是,window.performance.now()
返回的时间戳没有被限制在一毫秒的精确度内,相反,它们以浮点数的形式表示时间,精度最高可达微秒级。
另外一个不同点是,window.performance.now()
是以一个恒定的速率慢慢增加的,它不会受到系统时间的影响(系统时钟可能会被手动调整或被NTP等软件篡改)。另外,performance.timing.navigationStart + performance.now()
约等于 Date.now()
。
时间精度降低
为了提供对定时攻击和指纹的保护,performance.now()的精度可能会根据浏览器的设置而被舍弃。
在Firefox中,privacy.reduceTimerPrecision偏好是默认启用的,默认值为1ms。
// 降低时间精度 (1ms) 在 Firefox 60 performance.now(); // 8781416 // 8781815 // 8782206 // ... // 降低时间经度 当 `privacy.resistFingerprinting` 启用 performance.now(); // 8865400 // 8866200 // 8866700 // ...
在Firefox中,您还可以启用 privacy.resistFingerprinting
这将精度改为100ms或privacy.resistFingerprinting.reduceTimerPrecision.microseconds
的值,以较大者为准。
从Firefox 79开始,如果您使用Cross-Origin-Opener-Policy (en-US)和Cross-Origin-Embedder-Policy
头来跨源隔离您的文档,就可以使用高分辨率定时器。
Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
这些头确保顶层文档不会与跨源文档共享浏览上下文组。COOP过程--隔离你的文档,潜在的攻击者如果在弹出窗口中打开你的全局对象,就无法访问它,从而防止一组被称为 XS-Leaks 的跨源攻击。
规范
Specification | Status | Comment |
---|---|---|
High Resolution Time Level 2 performance.now() |
Recommendation | Stricter definitions of interfaces and types. |
High Resolution Time performance.now() |
Recommendation | Initial definition |
浏览器兼容性
BCD tables only load in the browser
相关链接
- When milliseconds are not enough: performance.now() from HTML5 Rocks