javascript基础学习系列三百三十一:计时API

页面性能始终是 Web 开发者关心的话题。Performance 接口通过 JavaScript API 暴露了浏览器内部 的度量指标,允许开发者直接访问这些信息并基于这些信息实现自己想要的功能。这个接口暴露在 window.performance 对象上。所有与页面相关的指标,包括已经定义和将来会定义的,都会存在于 这个对象上。
Performance 接口由多个 API 构成:  High Resolution Time API
 Performance Timeline API
 Navigation Timing API
 User Timing API
 Resource Timing API
 Paint Timing API
有关这些规范的更多信息以及新增的性能相关规范,可以关注 W3C 性能工作组的 GitHub 项目
页面。

High Resolution Time API

Date.now()方法只适用于日期时间相关操作,而且是不要求计时精度的操作。在下面的例子中, 函数 foo()调用前后分别记录了一个时间戳:

   const t0 = Date.now();
    foo();
    const t1 = Date.now();
    const duration = t1 – t0;
    console.log(duration);

考虑如下 duration 会包含意外值的情况。
 d u r a t i o n 是 0 。D a t e . n o w ( ) 只 有 毫 秒 级 精 度 ,如 果 f o o ( ) 执 行 足 够 快 ,则 两 个 时 间 戳 的 值 会 相 等 。  duration 是负值或极大值。如果在 foo()执行时,系统时钟被向后或向前调整了(如切换到夏
令时),则捕获的时间戳不会考虑这种情况,因此时间差中会包含这些调整。 为此,必须使用不同的计时 API 来精确且准确地度量时间的流逝。High Resolution Time API 定义了 window.performance.now(),这个方法返回一个微秒精度的浮点值。因此,使用这个方法先后捕获
注意 浏览器通常支持被废弃的Level1和作为替代的Level2。本节尽量介绍Level2级 规范。

计时 API

的时间戳更不可能出现相等的情况。而且这个方法可以保证时间戳单调增长。

const t0 = performance.now();
const t1 = performance.now();
console.log(t0);       // 1768.625000026077
console.log(t1);       // 1768.6300000059418
const duration = t1 – t0;
console.log(duration); // 0.004999979864805937
``

performance.now()计时器采用相对度量。这个计时器在执行上下文创建时从 0 开始计时。例如, 打开页面或创建工作线程时,performance.now()就会从 0 开始计时。由于这个计时器在不同上下文中初 18 始化时可能存在时间差,因此不同上下文之间如果没有共享参照点则不可能直接比较 performance.now()。 performance.timeOrigin 属性返回计时器初始化时全局系统时钟的值。
```js
   const relativeTimestamp = performance.now();
const absoluteTimestamp = performance.timeOrigin + relativeTimestamp;
    console.log(relativeTimestamp); // 244.43500000052154
    console.log(absoluteTimestamp); // 1561926208892.4001

注意 通过使用performance.now()测量L1缓存与主内存的延迟差,幽灵漏洞(Spectre) 可以执行缓存推断攻击。为弥补这个安全漏洞,所有的主流浏览器有的选择降低 performance.now()的精度,有的选择在时间戳里混入一些随机性。WebKit 博客上有一篇 相关主题的不错的文章“What Spectre and Meltdown Mean For WebKit”,作者是 Filip Pizlo。
Performance Timeline API 使用一套用于度量客户端延迟的工具扩展了 Performance 接口。性能度 量将会采用计算结束与开始时间差的形式。这些开始和结束时间会被记录为 DOMHighResTimeStamp 值,而封装这个时间戳的对象是 PerformanceEntry 的实例。
浏览器会自动记录各种 PerformanceEntry 对象,而使用 performance.mark()也可以记录自定 义的 PerformanceEntry 对象。在一个执行上下文中被记录的所有性能条目可以通过 performance. getEntries()获取:

console.log(performance.getEntries());
// [PerformanceNavigationTiming, PerformanceResourceTiming, ... ]

这个返回的集合代表浏览器的性能时间线(performance timeline)。每个 PerformanceEntry 对象 都有 name、entryType、startTime 和 duration 属性:

   const entry = performance.getEntries()[0];
    console.log(entry.name); // "https://foo.com"
console.log(entry.entryType); // navigation
console.log(entry.startTime); // 0
console.log(entry.duration); // 182.36500001512468 28

不过,PerformanceEntry 实际上是一个抽象基类。所有记录条目虽然都继承 PerformanceEntry, 但最终还是如下某个具体类的实例:
 PerformanceMark
 PerformanceMeasure
 PerformanceFrameTiming
 PerformanceNavigationTiming  PerformanceResourceTiming  PerformancePaintTiming
上面每个类都会增加大量属性,用于描述与相应条目有关的元数据。每个实例的 name 和 entryType 属性会因为各自的类不同而不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值