performance.now() 返回毫秒级浮点数,精度达微秒(小数点后三位),但单位仍是毫秒;它基于单调时钟,不受系统时间调整影响,适合高精度性能测量,但需注意后台节流、timeorigin偏移及统计方法以减少噪声。

performance.now() 返回的是毫秒级浮点数,不是微秒级——这是最常被误解的前提。它精度可达微秒(sub-millisecond),但单位仍是毫秒,小数点后三位对应微秒(例如 123.456 表示 123 毫秒 + 456 微秒)。想靠它“获取微秒级时间戳”没问题,但别误以为返回值单位是微秒。
为什么 performance.now() 比 Date.now() 更适合性能测量
Date.now() 受系统时钟调整(NTP 同步、手动改时间)影响,可能跳变或倒退;performance.now() 基于单调递增的高精度计时器(通常来自硬件 TSC 或类似机制),只关心相对耗时,不受系统时间干扰。
- 同一页面内多次调用,差值稳定可靠;跨页面或长时运行需注意
performance.timeOrigin偏移 - 在 Chrome/Firefox/Safari/Edge 中默认精度约 1–5 微秒(实际取决于 OS 和硬件),但受浏览器节流策略影响:后台标签页中
performance.now()调用频率会被限制(如每秒最多 100 次),导致连续采样失真 - 不要用它生成“绝对时间戳”——
performance.timeOrigin是页面加载起始时间(Date.now()单位),需相加才能转成可读时间,且该值本身也有约 1ms 的不确定性
如何安全地测量短函数执行时间(避免噪声干扰)
单次 performance.now() 差值容易被 JS 引擎优化、GC、CPU 频率波动干扰。真正有效的微基准测试必须结合统计与控制变量。
- 至少运行 100 次以上,并剔除首尾各 10% 的极值(避免 JIT 预热/突发 GC 影响)
- 用
performance.mark()+performance.measure()替代手算差值,更易与 DevTools 时间轴对齐 - 关键:强制同步执行——避免
await、setTimeout或事件循环让出,否则测的是调度延迟而非代码本身 - 示例:测
JSON.parse开销
const str = '{"a":1,"b":[1,2,3]}';
const times = [];
for (let i = 0; i <h3>常见误用与兼容性陷阱</h3><p>看似简单,实则几个坑能让你的“极致调优”数据完全失效。</p>
-
performance.now()在 Web Worker 中可用,但在 Service Worker 初始化阶段(fetch 事件前)可能未就绪,建议先检查typeof performance !== 'undefined' - Node.js 从 v8.5+ 提供
process.hrtime.bigint()(纳秒级),但performance.now()需通过require('perf_hooks').performance显式启用,且默认不挂载到全局performance对象 - 某些旧版 iOS Safari(≤14.5)对
performance.now()的精度会降级为 1ms(即使文档声称支持高精度),若目标用户含大量 iPad 用户,建议运行时探测:performance.now() === performance.now()连续两次调用结果相同即大概率被降级 - 不要在循环内高频打点(如每帧 60 次
performance.mark()),Chrome DevTools 的 Performance 面板可能丢弃部分标记,且影响主线程调度
真正的“极致调优”不在于追求 0.001ms 的差异,而在于识别出那个被重复执行上千次、每次慢 0.05ms 的函数——这时 performance.now() 才真正发挥价值。其余时候,过度关注微秒级抖动,往往意味着你还没找到真正的瓶颈。










