web前端性能监控window.performance对象介绍

4050 4 年前
Performance API用于精确度量、控制、增强浏览器的性能表现。这个API为测量网站性能,提供以前没有办法做到的精度。

window.performance 是W3C性能小组引入的新的API,目前IE9以上的浏览器都支持。一个performance对象的完整结构如下图所示:

memory 字段

memory字段代表JavaScript对内存的占用。

navigation 对象

navigation字段统计的是一些网页导航相关的数据。

redirectCount

navigation.redirectCount网页经过了多少次重定向跳转,但是这个接口有同源策略限制,即仅能检测同源的重定向;

type

navigation.type 返回值应该是0,1,2 中的一个。分别对应三个枚举值:

  • 0:网页通过点击链接、地址栏输入、表单提交、脚本操作等方式加载,相当于常数performance.navigation.TYPE_NAVIGATENEXT
  • 1:网页通过“重新加载”按钮或者location.reload()方法加载,相当于常数performance.navigation.TYPE_RELOAD
  • 2:网页通过“前进”或“后退”按钮加载,相当于常数performance.navigation.TYPE_BACK_FORWARD
  • 255:任何其他来源的加载,相当于常数performance.navigation.TYPE_UNDEFINED

timing 对象

timing字段它包含了网络、解析等一系列的时间数据,其整体结构如下图所示:

timing字段提供浏览器处理网页各个阶段的耗时。比如,performance.timing.navigationStart就是浏览器处理当前网页的启动时间。

得到页面加载的耗时、域名解析的耗时、TCP连接的耗时、读取页面第一个字节之前的耗时

var t = performance.timing;
var pageloadtime = t.loadEventStart - t.navigationStart;
var dns = t.domainLookupEnd - t.domainLookupStart;
var tcp = t.connectEnd - t.connectStart;
var ttfb = t.responseStart - t.navigationStart;

performance.timing对象包含以下属性(全部为只读):

navigationStart

当前浏览器窗口的前一个网页关闭,发生unload事件时的Unix毫秒时间戳。如果没有前一个网页,则等于fetchStart属性。

unloadEventStart

如果前一个网页与当前网页属于同一个域名,则返回前一个网页的unload事件发生时的Unix毫秒时间戳。如果没有前一个网页,或者之前的网页跳转不是在同一个域名内,则返回值为0。

unloadEventEnd

如果前一个网页与当前网页属于同一个域名,则返回前一个网页unload事件的回调函数结束时的Unix毫秒时间戳。如果没有前一个网页,或者之前的网页跳转不是在同一个域名内,则返回值为0。

redirectStart

返回第一个HTTP跳转开始时的Unix毫秒时间戳。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。

redirectEnd

返回最后一个HTTP跳转结束时(即跳转回应的最后一个字节接受完成时)的Unix毫秒时间戳。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。

fetchStart

返回浏览器准备使用HTTP请求读取文档时的Unix毫秒时间戳。该事件在网页查询本地缓存之前发生。

domainLookupStart

返回域名查询开始时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。

domainLookupEnd

返回域名查询结束时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。

connectStart

返回HTTP请求开始向服务器发送时的Unix毫秒时间戳。如果使用持久连接(persistent connection),则返回值等同于fetchStart属性的值。

connectEnd

返回浏览器与服务器之间的连接建立时的Unix毫秒时间戳。如果建立的是持久连接,则返回值等同于fetchStart属性的值。连接建立指的是所有握手和认证过程全部结束。

secureConnectionStart

返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。

requestStart

返回浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的Unix毫秒时间戳。

responseStart

返回浏览器从服务器收到(或从本地缓存读取)第一个字节时的Unix毫秒时间戳。

responseEnd

返回浏览器从服务器收到(或从本地缓存读取)最后一个字节时(如果在此之前HTTP连接已经关闭,则返回关闭时)的Unix毫秒时间戳。

domLoading

返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的readystatechange事件触发时)的Unix毫秒时间戳。

domInteractive

返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、相应的readystatechange事件触发时)的Unix毫秒时间戳。

domContentLoadedEventStart

返回当前网页DOMContentLoaded事件发生时(即DOM结构解析完毕、所有脚本开始运行时)的Unix毫秒时间戳。

domContentLoadedEventEnd

返回当前网页所有需要执行的脚本执行完成时的Unix毫秒时间戳。

domComplete

返回当前网页DOM结构生成时(即Document.readyState属性变为“complete”,以及相应的readystatechange事件发生时)的Unix毫秒时间戳。

loadEventStart

返回当前网页load事件的回调函数开始时的Unix毫秒时间戳。如果该事件还没有发生,返回0。

loadEventEnd

返回当前网页load事件的回调函数运行结束时的Unix毫秒时间戳。如果该事件还没有发生,返回0。

网页加载整个过程的耗时的计算方法如下:

var t = performance.timing; 
var pageLoadTime = t.loadEventEnd - t.navigationStart;

DNS查询耗时、白屏时间、domready等。如下:

  • DNS查询耗时 = domainLookupEnd - domainLookupStart
  • TCP链接耗时 = connectEnd - connectStart
  • request请求耗时 = responseEnd - responseStart
  • 解析dom树耗时 = domComplete - domInteractive
  • 白屏时间 = domloadng - fetchStart
  • domready时间 = domContentLoadedEventEnd - fetchStart
  • onload时间 = loadEventEnd - fetchStart
var timing = window.performance && window.performance.timing;
var navigation = window.performance && window.performance.navigation;


//重定向次数:
var redirectCount = navigation && navigation.redirectCount;

//跳转耗时:
var redirect = timing.redirectEnd - timing.redirectStart;

//APP CACHE 耗时:
var appcache = Math.max(timing.domainLookupStart - timing.fetchStart, 0);

//DNS 解析耗时:
var dns = timing.domainLookupEnd - timing.domainLookupStart;

//TCP 链接耗时:
var conn = timing.connectEnd - timing.connectStart;

//等待服务器响应耗时(注意是否存在cache):
var request = timing.responseStart - timing.requestStart;

//内容加载耗时(注意是否存在cache):
var response = timing.responseEnd - timing.responseStart;

//总体网络交互耗时,即开始跳转到服务器资源下载完成:
var network = timing.responseEnd - timing.navigationStart;

//渲染处理:
var processing = (timing.domComplete || timing.domLoading) - timing.domLoading;

//抛出 load 事件:
var load = timing.loadEventEnd - timing.loadEventStart;

//总耗时:
var total = (timing.loadEventEnd || timing.loadEventStart || timing.domComplete || timing.domLoading) - timing.navigationStart;

//可交互:
var active = timing.domInteractive - timing.navigationStart;

//请求响应耗时,即 T0,注意cache:
var t0 = timing.responseStart - timing.navigationStart;

//首次出现内容,即 T1:
var t1 = timing.domLoading - timing.navigationStart;

//内容加载完毕,即 T3:
var t3 = timing.loadEventEnd - timing.navigationStart;

performance.now 方法

performance.now方法返回当前网页自从performance.timing.navigationStart到当前时间之间的微秒数(毫秒的千分之一)。也就是说,它的精度可以达到100万分之一秒。

performance.now() 
// 23493457.476999998

Date.now() - (performance.timing.navigationStart + performance.now())
// -0.64306640625

上面代码表示,performance.timing.navigationStart加上performance.now(),近似等于Date.now(),也就是说,Date.now()可以替代performance.now()。但是,前者返回的是毫秒,后者返回的是微秒,所以后者的精度比前者高1000倍。

通过两次调用performance.now方法,可以得到间隔的准确时间,用来衡量某种操作的耗时。

var start = performance.now();
doTasks();
var end = performance.now();

console.log('耗时:' + (end - start) + '微秒。');

performance.mark 等方法

用于做标记和清除标记,供用户自定义统计一些数据,比如某函数运行耗时等

window.performance.mark('mark_fully_loaded');

clearMarks方法用于清除标记,如果不加参数,就表示清除所有标记。

window.peformance.clearMarks('mark_fully_loaded');

window.performance.clearMarks();

mark(name),measure(name, startMark, endMark),clearMarks(),clearMeasures()

  • name:自定义的名称,不要和getEntries()返回的数组中其他name重复
  • startMark:作为开始时间的标记名称或PerformanceTiming的一个属性
  • endMark:作为结束时间的标记名称或PerformanceTiming的一个属性

创建标记:mark(name); 记录两个标记的时间间隔:measure(name, startMark, endMark); 清除指定标记:window.performance.clearMarks(name); 清除所有标记:window.performance.clearMarks(); 清除指定记录间隔数据:window.performance.clearMeasures(name); 清除所有记录间隔数据:window.performance.clearMeasures();

performance.getEntries 方法

浏览器获取网页时,会对网页中每一个对象(脚本文件、样式表、图片文件等等)发出一个HTTP请求。performance.getEntries方法以数组形式,返回这些请求的时间统计信息,有多少个请求,返回数组就会有多少个成员。

由于该方法与浏览器处理网页的过程相关,所以只能在浏览器中使用。

window.performance.getEntries()[0]

// PerformanceResourceTiming { 
//   responseEnd: 4121.6200000017125, 
//   responseStart: 4120.0690000005125, 
//   requestStart: 3315.355000002455, 
//   ...
// }

上面代码返回第一个HTTP请求(即网页的HTML源码)的时间统计信息。该信息以一个高精度时间戳的对象形式返回,每个属性的单位是微秒(microsecond),即百万分之一秒。

该对象的属性中除了包含资源加载时间还有以下五个属性。

  • name:资源名称,是资源的绝对路径或调用mark方法自定义的名称
  • startTime:开始时间
  • duration:加载时间
  • entryType:资源类型,entryType类型不同数组中的对象结构也不同!具体见下
  • initiatorType:谁发起的请求,具体见下

entryType的值:

该类型对象 描述
mark PerformanceMark 通过mark()方法添加到数组中的对象
measure PerformanceMeasure 通过measure()方法添加到数组中的对象
resource PerformanceResourceTiming 所有资源加载时间,用处最多
navigation PerformanceNavigationTiming 现除chrome和Opera外均不支持,导航相关信息
frame PerformanceFrameTiming 现浏览器均未支持
server PerformanceServerTiming 未查到相关资料

initiatorType的值:

发起对象 描述
a Element link/script/img/iframe等 通过标签形式加载的资源,值是该节点名的小写形式
a CSS resourc css 通过css样式加载的资源,比如background的url方式加载资源
a XMLHttpRequest object xmlhttprequest 通过xhr加载的资源
a PerformanceNavigationTiming object navigation 当对象是PerformanceNavigationTiming时返回
/根据entryType类型返回的不同对象

PerformanceMark:{  //通过mark()方法添加的对象
    entryType:"mark"
    name:调用mark()方法时自定义的名字
    startTime: 做标记的时间
    duration:0
}

PerformanceMeasure:{  //通过measure()方法添加的对象
    entryType:"measure"
    name:调用measure()方法时自定义的名字
    startTime: 开始量的时间
    duration:标记的两个量的时间间隔
}
PerformanceResourceTiming:{  //可以用来做一个精准的进度条
    entryType:"resource"
    name:资源的绝对路径,即URL
    startTime: 即将抓取资源的时间,
    duration: responseEnd - startTime
    initiatorType:略!/:傲娇脸
    //其他属性请参考performance.timing
}
PerformanceNavigationTiming:{
    entryType:"navigation"
    name:本页路由,即地址栏看到的地址
    startTime: 0
    duration: loadEventEnd - startTime 
    initiatorType:"navigation"
    //其他属性请参考performance.timing
}
© 2018邮箱:11407215#qq.comGitHub沪ICP备12039518号-6