Performace API
Performance 接口可以获取到当前页面中与性能相关的信息。它是 High Resolution Time API 的一部分,同时也融合了 Performance Timeline API、Navigation Timing API、 User Timing API 和 Resource Timing API。
Performance对象
通过window.performace只读属性可获取Performance对象。
Performace 接口在 Web Worker 中可用,但 performance 的创建和衡量需在同一环境下,在主线程创建的performance,在其他 worker 线程中是不可用的。
Performance对象属性
- timeOrigin:性能测试开始时间戳(实验中)
- memory:基本内存使用情况(chrome扩展的非标准属性)
- jsHeapSizeLimit:上下文内可用堆最大体积字节数量
- totalJSHeapSize:已分配堆体体积字节数量
- usedJSHeapSize:当前 JS 堆活跃段(segment)体积字节数量
- navigation:指定时间段内操作相关(加载、刷新、重定向等)
- type:
- TYPE_NAVIGATE :navigate(URL直达、超链接、表单提交、脚本跳转)
- TYPE_RELOAD :reload
- TYPE_BACK_FORWARD :forward or back
- TYPE_RESERVED :other
- redirectCount:到达当前页面前重定向次数
- type:
- timing:各项时间戳数据(已废弃?)
请求阶段:- redirectStart 第一次重定向开始时时间戳,若无重定向或上次重定向不同源则为0
- redirectEnd 最后一次重定向完成,即HTTP响应的最后一个字节返回时的时间戳,若无重定向或上次重定向不同源则为0
- fetchStart 浏览器准备通过HTTP请求去获取页面的时间戳
- domainLookupStart 域名查询开始时间戳。若为持久连接,或从本地缓存获取则等同于fetchStart
- domainLookupEnd 域名查询结束时的时间戳。若为持久连接,或从本地缓存获取则等同于fetchStart
- connectStart 浏览器与服务器开始建立连接的时间戳,若为持久连接,则等同于fetchStart
- secureConnectionStart 浏览器与服务器开始安全链接握手的时间戳。若不要求安全连接则为0
- connectEnd 浏览器与服务器连接建立完成的时间戳,即所有握手和认证过程全部完成
- requestStart 浏览器向服务器发出HTTP请求(或开始读取本地缓存时)的时间戳
- responseStart 浏览器从服务器收到(或从本地缓存读取)第一个字节时的时间戳
- responseEnd 浏览器从服务器收到(或从本地缓存读取)最后一个字节时(若在此之前HTTP连接已经关闭,则返回关闭时)的时间戳
渲染阶段: - domLoading 当前网页DOM开始加载的时间戳,即document.readyState属性变为“loading”,且触发对应readyStateChange事件时。
- domInteractive 当前网页DOM解析完成、开始加载子资源(如css、图片等)的时间戳,即document.readyState属性变为“interactive”,且触发对应readyStateChange事件时。
- domComplete 当前网页DOM解析完成且内嵌资源加载完成的时间戳,即document.readyState属性变为“complete”,且触发对应readyStateChange事件时。
- domContentLoadedEventStart 当前网页DOM加载完成、所有脚本开始运行的时间戳,即document的DOMContentLoaded事件被触发时。
- domContentLoadedEventEnd 当前网页DOM加载完成、所有脚本运行完成的时间戳。
- loadEventStart 当前网页加载完成,window的load事件回调函数开始执行的时间戳,若该事件还没发生则为0。
- loadEventEnd 当前网页加载完成,window的load事件回调函数开始执行的时间戳,若该事件还没发生则为0。
- navigationStart 当前浏览器窗口的前一个网页关闭,发生unload事件时的时间戳。如果没有前一个网页,则等于fetchStart
- unloadEventStart 如果前一个网页与当前网页同域,则为前一个网页的unload事件发生时的时间戳。如果没有前一个网页或之前网页跳转不同域,则为0。
- unloadEventEnd 如果前一个网页与当前网页同域,则为前一个网页的unload事件回调执行结束的时间戳。如果没有前一个网页或之前网页跳转不同域,则为0。
Performance对象方法
- Performance.mark( name ):使用 name 名称创建一个timestamp
- Performance.measure( name, startMark, endMark ): 使用 name 名称创建一个从startMark开始到endMark结束的measure(测量)
- Performance.getEntries(filter):返回由基于给定 filter 的 PerformanceEntry 对象组成的列表,filter格式为{name : “measureName”, entryType: “measure”},如果没有传入filter参数,则返回全部 PerformanceEntry对象组成的列表
- Performance.getEntriesByType(type):返回一个由指定type的 PerformanceEntry 对象组成的列表
- Performance.getEntriesByName(name, type):返回由指定 name 和 type的 PerformanceEntry 对象组成的列表
- Performance.clearMarks(name): 删除所有名为name的 mark 类型 entry,如果没有传入name参数,则删除所有 mark 类型 entry
- Performance.clearMeasures(name): 删除所有名为name的 measure 类型 entry ,如果没有传入name参数,则删除所有measure 类型 entry
- Performance.clearResourceTimings(): 删除所有 resource 类型 entry
- Performance.now():返回从性能测量开始到现在的毫秒数
- Performance.setResourceTimingBufferSize(maxSize):设置浏览器性能测量缓冲区中 可维持的resource 类型 entry 对象的最大数量
- Performance.toJSON():返回 Performance 对象的 JSON 对象
示例
Performace Timing
Performance Timing 以三种基于特制化过滤标准提供不同机制进行性能测试记录的方法扩展了Performance对象。
function doSomething(n) {
for (var i=0 ; i < n; i++) {
var m = Math.random();
}
}
//返回从性能测量开始到现在的毫秒数
performance.now()
// 创建 名为 "Begin" 的 mark 类型 entry
performance.mark("Begin");
// 重复创建同名 mark 会将之前创建的 mark 覆盖
performance.mark("Begin");
doSomething(50000);
// 创建 名为 "End" 的 mark 类型 entry
performance.mark("End");
doSomething(50000);
// 创建 名为 "Measure" 的 measure 类型 entry,用以测量"Begin"和"End" 间的耗时
performance.measure("Measure", "Begin", "End");
// 获取 名为 "Begin" 的 mark类型 entry数组
var entries = performance.getEntriesByName("Begin", "mark");
// 获取 名为 "Begin" 的 entry数组
var entries = performance.getEntriesByName("Begin");
// 获取 mark 类型 entry 数组
var entries = performance.getEntriesByType("mark");
// 获取 指定删选条件的 entry 数组
var entries = performance.getEntries({
name : "Measure",
entryType: "measure"
});
// 获取 所有 entry 数组
var entries = performance.getEntries();
for (var i=0; i < entries.length; i++) {
console.log("All Entry[" + i + "]" + entries[i]);
console.log("name: " + entries[i].name +
"; entryType: " + entries[i].entryType +
"; startTime: " + entries[i].startTime +
"; duration: " + entries[i].duration);
}
//返回 Performance 对象的 JSON 对象
performance.toJSON():
//删除所有名为'Begin'的 mark 类型 entry
performance.clearMarks('Begin')
// 删除所有 mark 类型 entry
performance.clearMarks()
//删除所有名为'measure'的 measure 类型 entry
performance.clearMeasures('measure')
//删除所有measure 类型 entry
performance.clearMeasures('measure')
Resource Timing API
Resource Timing API 提供了获取和分析应用程序资源加载的详细网络计时数据的一种途径。
应用可以使用一些可量化的时间度量标准,如加载特定资源的时长。
这些资源可能是 XMLHttpRequest, SVG、图片、脚本等等。
function calculateLoadTimes() {
// 判断是否支持 performance
if (performance === undefined) {
console.log("= Calculate Load Times: performance NOT supported");
return;
}
// 获取 "resource" 类型 performance entries 列表
var resources = performance.getEntriesByType("resource");
if (resources === undefined || resources.length <= 0) {
console.log("= Calculate Load Times: there are NO `resource` performance records");
return;
}
console.log("= Calculate Load Times");
for (var i=0; i < resources.length; i++) {
console.log("== Resource[" + i + "] - " + resources[i].name);
// 重定向时间
var t = resources[i].redirectEnd - resources[i].redirectStart;
console.log("... Redirect time = " + t);
// DNS 时间
t = resources[i].domainLookupEnd - resources[i].domainLookupStart;
console.log("... DNS lookup time = " + t);
// TCP 握手时间
t = resources[i].connectEnd - resources[i].connectStart;
console.log("... TCP time = " + t);
// 可靠连接时间
t = (resources[i].secureConnectionStart > 0) ? (resources[i].connectEnd - resources[i].secureConnectionStart) : "0";
console.log("... Secure connection time = " + t);
// 响应时间
t = resources[i].responseEnd - resources[i].responseStart;
console.log("... Response time = " + t);
// fetchStart 直到响应结束
t = (resources[i].fetchStart > 0) ? (resources[i].responseEnd - resources[i].fetchStart) : "0";
console.log("... Fetch until response end time = " + t);
// 请求开始到响应结束
t = (resources[i].requestStart > 0) ? (resources[i].responseEnd - resources[i].requestStart) : "0";
console.log("... Request start until response end time = " + t);
// Start 直到响应结束
t = (resources[i].startTime > 0) ? (resources[i].responseEnd - resources[i].startTime) : "0";
console.log("... Start until response end time = " + t);
}
}
function setResourceTimingBufferSize(maxSize) {
if (performance === undefined) {
console.log("Browser does not support Web Performance");
return;
}
var supported = typeof performance.setResourceTimingBufferSize == "function";
if (supported) {
console.log("... Performance.setResourceTimingBufferSize() = Yes");
//设置浏览器性能测量缓冲区中 可维持的resource 类型 entry 对象的最大数量
//通常不低于150
performance.setResourceTimingBufferSize(maxSize);
} else {
console.log("... Performance.setResourceTimingBufferSize() = NOT supported");
}
}
setResourceTimingBufferSize(256)
calculateLoadTimes()
//删除所有 resource 类型 entry
performance.clearResourceTimings()