页面性能一直都是 web 开发人员比较关注的领域。但在实际应用中,度量页面性能的指标,是 javascript 的。Web Timing API 改变了这个局面,让开发人员通过 javascript 就能使用浏览器内部的度量结果,给出了页面加载和渲染过程的很多信息,对性能优化非常有价值。本文将详细介绍 web Timing API——performance 对象
Web 计时机制的核心是 window.performance 对象。对页面的所有度量信息,包括那些规范中已经定义的和将来才能确定的,都包含在这个对象里面。performance 对象包括 navigation 和 timing 对象,以及 chrome 扩展的 memory 对象,还包括 getEntries() 和 now() 两个方法
值得高兴的是,低版本 IE 也支持 performance 对象
memory 属性是 chrome 扩展的对象,只有 chrome 浏览器支持,包含以下三个属性:
jsHeapSizeLimit 表示内存大小限制
totalJSHeapSize 表示可使用的内存
usedJSHeapSize 表示 javascript 对象占用的内存
- /*
- jsHeapSizeLimit: 793000000
- totalJSHeapSize: 10000000
- usedJSHeapSize: 10000000
- */
- console.log(performance.memory);
performance.navigation 属性是一个对象,包含着与页面导航有关的 redirectCount 和 type 这两个属性
其中 redirectCount 表示页面加载前的重定向次数;而 type 是一个数值常量,表示刚刚发生的导航类型,type 有以下取值
- performance.navigation.TYPE_NAVTGATE(0):页面第一次加载
- performance.navigation.TYPE_RELOAD(1):页面重载过
- performance.navigation.TYPE_BACK_FORWARD(2):页面是通过"后退"或"前进"按钮打开的
- console.log(window.performance.navigation.redirectCount); //0
- console.log(window.performance.navigation.type); //1
performance.timing 属性也是一个对象,但这个对象的属性都是时间戳,不同的事件会产生不同的时间值
下图显示了一个请求发出的整个过程中,各种环节的时间顺序
下面按照时间顺序对 timing 对象的各个属性进行说明
navigationStart: 开始导航到当前页面的时间,即在地址栏输入地址后按下回车时的时间
- var navigationStart = performance.timing.navigationStart;
- //1488984540668
- console.log(navigationStart);
- //Wed Mar 08 2017 22:49:44 GMT+0800 (中国标准时间)
- console.log(new Date(new Date(navigationStart)));
redirectStart: 到当前页面的重定向开始的时间。但只有在重定向的页面来自同一个域时这个属性才会有值;否则,值为 0
redirectEnd: 到当前页面的重定向结束的时间。但只有在重定向的页面来自同一个域时这个属性才会有值;否则,值为 0
- console.log(performance.timing.redirectStart); //0
- console.log(performance.timing.redirectEnd); //0
fetchStart: 开始通过 HTTP GET 取得页面的时间
- console.log(performance.timing.fetchStart); //1488984540668
domainLookupStart: 开始査询当前页面 DNS 的时间,如果使用了本地缓存或持久连接,则与 fetchStart 值相等
domainLookupEnd: 査询当前页面 DNS 结束的时间,如果使用了本地缓存或持久连接,则与 fetchStart 值相等
- console.log(performance.timing.domainLookupStart); //1488984540670
- console.log(performance.timing.domainLookupEnd); //1488984540671
connectStart: 浏览器尝试连接服务器的时间
secureConnectionStart: 浏览器尝试以 SSL 方式连接服务器的时间。不使用 SSL 方式连接时,这个属性的值为 0
connectEnd: 浏览器成功连接到服务器的时间
- console.log(performance.timing.connectStart); //1488984540671
- console.log(performance.timing.secureConnectionStart); //0
- console.log(performance.timing.connectEnd); //1488984540719
requestStart: 浏览器开始请求页面的时间
responseStart: 浏览器接收到页面第一字节的时间
responseEnd: 浏览器接收到页面所有内容的时间
- console.log(performance.timing.requestStart); //1488984540720
- console.log(performance.timing.responseStart); //1488984540901
- console.log(performance.timing.responseEnd); //1488984540902
unloadEventStart: 前一个页面的 unload 事件开始的时间。但只有在前一个页面与当前页面来自同一个域时这个属性才会有值;否则,值为 0
unloadEventEnd: 前一个页面的 unload 事件结束的时间。但只有在前一个页面与当前页面来自同一个域时这个属性才会有值;否则,值为 0
- console.log(performance.timing.unloadEventStart); //1488984540902
- console.log(performance.timing.unloadEventEnd); //1488984540903
domLoading:document.readyState 变为 "loading" 的时间,即开始解析 DOM 树的时间
domInteractive:document.readyState 变为 "interactive" 的时间,即完成完成解析 DOM 树的时间
domContentLoadedEventStart: 发生 DOMContentloaded 事件的时间,即开始加载网页内资源的时间
domContentLoadedEventEnd:DOMContentLoaded 事件已经发生且执行完所有事件处理程序的时间,网页内资源加载完成的时间
domComplete:document.readyState 变为 "complete" 的时间,即 DOM 树解析完成、网页内资源准备就绪的时间
- console.log(performance.timing.domLoading); //1488984540905
- console.log(performance.timing.domInteractive); //1488984540932
- console.log(performance.timing.domContentLoadedEventStart); //1488984540932
- console.log(performance.timing.domContentLoadedEventEnd); //1488984540932
- console.log(performance.timing.domComplete); //1488984540932
loadEventStart: 发生 load 事件的时间,也就是 load 回调函数开始执行的时间
loadEventEnd:load 事件已经发生且执行完所有事件处理程序的时间
- console.log(performance.timing.loadEventStart); //1488984540933
- console.log(performance.timing.loadEventEnd); //1488984540933
[注意] 在实际情况下,通过 performance.timing 属性可以找到 domInteractive、domContentLoadedEventStart、domContentLoadedEventEnd、domComplete、loadEventStart 和 loadEventEnd 这 6 个值。但是在单独获取的情况下,这 6 个值都为 0
- /*
- connectEnd:1488989686331
- connectStart:1488989686330
- domComplete:1488989686395
- domContentLoadedEventEnd:1488989686395
- domContentLoadedEventStart:1488989686393
- domInteractive:1488989686393
- domLoading:1488989686336
- domainLookupEnd:1488989686330
- domainLookupStart:1488989686330
- fetchStart:1488989686328
- loadEventEnd:1488989686395
- loadEventStart:1488989686395
- navigationStart:1488989686328
- redirectEnd:0
- redirectStart:0
- requestStart:1488989686331
- responseEnd:1488989686333
- responseStart:1488989686332
- secureConnectionStart:0
- unloadEventEnd:1488989686333
- unloadEventStart:1488989686333
- */
- console.log(performance.timing);
- /*
- navigationStart:1488989686328
- unloadEventStart:1488989686333
- unloadEventEnd:1488989686333
- redirectStart:0
- redirectEnd:0
- fetchStart:1488989686328
- domainLookupStart:1488989686330
- domainLookupEnd:1488989686330
- connectStart:1488989686330
- connectEnd:1488989686331
- secureConnectionStart:0
- requestStart:1488989686331
- responseStart:1488989686332
- responseEnd:1488989686333
- domLoading:1488989686336
- domInteractive:0
- domContentLoadedEventStart:0
- domContentLoadedEventEnd:0
- domComplete:0
- loadEventStart:0
- loadEventEnd:0
- */
- var timing = performance.timing;
- for(var value in timing){
- console.log(value + ':'+timing[value]);
- }
getEntries() 方法将返回一个数组,包含了页面中所有的 HTTP 资源请求
[注意]IE8 - 浏览器不支持
以下面的页面为例,可知页面有 jquery 一个资源的请求
结果如下图所示,由于只有一个资源,所以该资源处于 performance.getEntries()[0] 中
其中,duration 表示加载时间;name 表示资源的绝对路径;entryType 表示资源类型;initiatorType 表示发起请求的标签
now() 方法返回从页面初始化到调用该方法时的毫秒数
[注意]IE9 - 浏览器不支持
performance.now() 与 Date.now() 不同的是,返回了以微秒为单位的时间,更加精准
并且与 Date.now() 会受系统程序执行阻塞的影响不同,performance.now() 的时间是以恒定速率递增的,不受系统时间的影响 (系统时间可被人为或软件调整)
Date.now() 输出的是 UNIX 时间,即距离 1970 年 1 月 1 日 0 点的时间,而 performance.now() 输出的是相对于 performance.timing.navigationStart(页面初始化) 的时间
- var t0 = window.performance.now();
- doSomething();
- var t1 = window.performance.now();
- console.log("doSomething函数执行了" + (t1 - t0) + "毫秒.")
通过 timing 属性的这些时间值,就可以全面了解页面在被加载到浏览器的过程中都经历了哪些阶段,而哪些阶段可能是影响性能的瓶颈
【重定向时间】
- times.redirect = timing.redirectEnd - timing.redirectStart;
- console.log(times.redirect); //0
【DNS 查询时间】
- times.lookupDomain = timing.domainLookupEnd - timing.domainLookupStart;
- console.log(times.lookupDomain); //1
【TCP 握手时间】
- times.connect = timing.connectEnd - timing.connectStart;
- console.log(times.connect); //48
【HTTP 响应时间】
通过浏览器发出 HTTP 请求,到浏览器接受完 HTTP 响应的时间
- times.request = timing.responseEnd - timing.requestStart;
- console.log(times.request); //182
最终,性能指标对象 times 表示如下
- var timing = performance.timing;
- var times = {
- redirect:timing.redirectEnd - timing.redirectStart,
- lookupDomain:timing.domainLookupEnd - timing.domainLookupStart,
- connect:timing.connectEnd - timing.connectStart,
- request:timing.responseEnd - timing.requestStart
- };
来源: http://www.cnblogs.com/xiaohuochai/p/6523397.html