初探Performance API

前段时间在读Vue源码的时候,发现了这样一个API——Window.Performance。当时彻底不知道这是什么?在查阅了一些资料后,大体明白了这个API的做用。下面一块儿来看看什么是Performance。
其实光看这个API的名字,咱们就能大体猜到这必定是和性能相关的。来看看MDN上关于它的介绍。html

The Performance interface provides access to performance-related information for the current page. It's part of the High Resolution Time API, but is enhanced by the Performance Timeline API, the Navigation Timing API, the User Timing API, and the Resource Timing API.

Performace接口容许访问当前页面性能相关的信息。它是High Resolution Time API的一部分。可是它被Performance Timeline API, the Navigation Timing API, the User Timing API, and the Resource Timing API扩展加强了。实际上Performance的主要功能都是由这几个API提供的。
单单看上面的内容,你们必定仍是会感到疑惑,这performace到底是个什么东西?ok,咱们直接打开百度的网页,而后在控制台里输出Window.performance(window.performace返回的就是performance对象)html5

图片描述

Performance对象里出现了4个属性。咱们分别来看看这4个属性都表明了什么意思?web

timing

timing对象提供了各类与浏览器处理相关的时间数据。具体以下表chrome

名称 做用(这里全部时间戳都表明UNIX毫秒时间戳)
connectEnd 浏览器与服务器之间的链接创建时的时间戳,链接创建指的是全部握手和认证过程所有结束
connectStart HTTP请求开始向服务器发送时的时间戳,若是是持久链接,则等同于fetchStart。
domComplete 当前网页DOM结构生成时,也就是Document.readyState属性变为“complete”,而且相应的readystatechange事件触发时的时间戳。
domContentLoadedEventEnd 当前网页DOMContentLoaded事件发生时,也就是DOM结构解析完毕、全部脚本运行完成时的时间戳。
domContentLoadedEventStart 当前网页DOMContentLoaded事件发生时,也就是DOM结构解析完毕、全部脚本开始运行时的时间戳。
domInteractive 当前网页DOM结构结束解析、开始加载内嵌资源时,也就是Document.readyState属性变为“interactive”、而且相应的readystatechange事件触发时的时间戳。
domLoading 当前网页DOM结构开始解析时,也就是Document.readyState属性变为“loading”、而且相应的readystatechange事件触发时的时间戳。
domainLookupEnd 域名查询结束时的时间戳。若是使用持久链接,或者从本地缓存获取信息的,等同于fetchStart
domainLookupStart 域名查询开始时的时间戳。若是使用持久链接,或者从本地缓存获取信息的,等同于fetchStart
fetchStart 浏览器准备经过HTTP请求去获取页面的时间戳。在检查应用缓存以前发生。
loadEventEnd 当前网页load事件的回调函数结束时的时间戳。若是该事件尚未发生,返回0。
loadEventStart 当前网页load事件的回调函数开始时的时间戳。若是该事件尚未发生,返回0。
navigationStart 当前浏览器窗口的前一个网页关闭,发生unload事件时的时间戳。若是没有前一个网页,就等于fetchStart
redirectEnd 最后一次重定向完成,也就是Http响应的最后一个字节返回时的时间戳。若是没有重定向,或者上次重定向不是同源的。则为0
redirectStart 第一次重定向开始时的时间戳,若是没有重定向,或者上次重定向不是同源的。则为0
requestStart 浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的时间戳。
responseEnd 浏览器从服务器收到(或从本地缓存读取)最后一个字节时(若是在此以前HTTP链接已经关闭,则返回关闭时)的时间戳
responseStart 浏览器从服务器收到(或从本地缓存读取)第一个字节时的时间戳。
secureConnectionStart 浏览器与服务器开始安全连接的握手时的时间戳。若是当前网页不要求安全链接,则返回0。
unloadEventEnd 若是前一个网页与当前网页属于同一个域下,则表示前一个网页的unload回调结束时的时间戳。若是没有前一个网页,或者以前的网页跳转不是属于同一个域内,则返回值为0。
unloadEventStart 若是前一个网页与当前网页属于同一个域下,则表示前一个网页的unload事件发生时的时间戳。若是没有前一个网页,或者以前的网页跳转不是属于同一个域内,则返回值为0。

了解上面timeing提供的各类属性以后,咱们能够计算出网页在加载时候某一部分消耗的具体时间,能够精确到千分之一毫秒。例如要计算出发送请求到接受完数据所消耗的时间。浏览器

const timing = window.performance.timing
const contactDuration = timing.responseEnd - timing.requestStart

navagation

PerformanceNavigation接口呈现了如何导航到当前文档的信息。PerformanceNavigation有两个属性,一个是type,表示如何导航到当前页面的,主要有4个值。缓存

  • type=0:表示当前页面是经过点击连接,书签和表单提交,或者脚本操做,或者在url中直接输入地址访问的。
  • type=1: 表示当前页面是点击刷新或者调用Location.reload()方法访问的。
  • type=2: 表示当前页面是经过历史记录或者前进后退按钮访问的。
  • type=255: 其余方式访问的

另一个属性是redirectCount,表示到达当前页面以前通过几回重定向。安全

其余属性

performance.timeOrigin

表示performance性能测试开始的时间。是一个高精度时间戳(千分之一毫秒)服务器

performance.onresourcetimingbufferfull

表示当浏览器资源时间性能缓冲区已满时会触发的回调函数。下面是mdn上关于这个属性的一个demo。这个demo的主要内容是当缓冲区内容满时,调用buffer_full函数。框架

function buffer_full(event) {
  console.log("WARNING: Resource Timing Buffer is FULL!");
  performance.setResourceTimingBufferSize(200);
}
function init() {
  // Set a callback if the resource buffer becomes filled
  performance.onresourcetimingbufferfull = buffer_full;
}
<body onload="init()">

performance.memory

一个非标准属性,由chrome浏览器提供。这个属性提供了一个能够获取到基本内存使用状况的对象。dom

Performance.mark

先来看看MDN中关于mark方法的定义

The mark() method creates a timestamp in the browser's performance entry buffer with the given name.

这段话能够分解出三个关键词。首先timestamp,这里的timestamp指的是高精度时间戳(千分之一毫秒),其次是performance entry buffer。performance entry buffer指的是存储performance实例对象的区域,初始值为空。最后就是given name,表示生成的每个timestamp都有相应的名称。
因此这句话就能够理解成,在浏览器的performance entry buffer中,根据名称生成高精度时间戳。也就是不少人说过的“打点”。

Performance.measure

一样先来看看MDN上关于measure的定义

The measure() method creates a named timestamp in the browser's performance entry buffer between two specified marks (known as the start mark and end mark, respectively). The named timestamp is referred to as a measure.

这段定义和上面mark的定义有些相似,其最核心的不一样点在于这句话。between two specified marks。因此measure是指定两个mark点之间的时间戳。若是说mark能够理解为"打点"的话,measure就能够理解为"连线"。

一个小例子

咱们来看一个使用mark和measure的小demo,这个例子也是引用MDN,这里作一下简单讲解。

// 标记一个开始点
performance.mark("mySetTimeout-start");

// 等待1000ms
setTimeout(function() {
  // 标记一个结束点
  performance.mark("mySetTimeout-end");

  // 标记开始点和结束点之间的时间戳
  performance.measure(
    "mySetTimeout",
    "mySetTimeout-start",
    "mySetTimeout-end"
  );

  // 获取全部名称为mySetTimeout的measures
  var measures = performance.getEntriesByName("mySetTimeout");
  var measure = measures[0];
  console.log("setTimeout milliseconds:", measure.duration)

  // 清除标记
  performance.clearMarks();
  performance.clearMeasures();
}, 1000);

结果如图
图片描述
能够看到,高精度的时间戳是很是精准的。(咱们知道因为执行队列的缘由,setTimeout不会在给定的1000ms以后就当即执行)
Performance API提供了不少方便测试咱们程序性能的接口。好比mark和measure。不少优秀的框架也用到了这个API进行测试,好比我最近在看的Vue框架。它里面就频繁用到了mark和measure来测试程序性能。因此想要开发高性能的web程序,了解Performace API仍是很是重要的。

参考资料

【1】MDN Performance, Performance
【2】User Timing API
【3】performace entry buffer

相关文章
相关标签/搜索