转自:http://blog.51cto.com/shuizhongyue/1718327
相似文件:http://www.alloyteam.com/2015/09/explore-performance/
说在前面@H_403_9@@H_403_9@最近身体出了点问题,折腾了个把星期总算活过来。差不多个把星期没写博客了,今天分享一个比较好玩的东东@H_403_9@—performance
上一篇博客中分享了很多页面性能的测试工具,通常,页面的性能问题也是我们开发中一个重要环节,但一直以来我们也没有没有比较好的手段,来检测页面的性能;通常,我们只能以来与@H_403_9@chrome或者@H_403_9@FF浏览器自带的@H_403_9@profile,@H_403_9@timming或者使用在线的@H_403_9@pagetest,阿里测等。我们很希望有一套页面性能的@H_403_9@api,我们可以自己编写代码测试页面性能而不需要借助于其他的工具。@H_403_9@
好在@H_403_9@W3C Web性能工作小组已经@H_403_9@
与各浏览器厂商都已认识到性能对于@H_403_9@web开发的重要性,为了解决当前性能测试的困难,@H_403_9@W3C推出了一套性能@H_403_9@API标准,各种浏览器对这套标准的支持如今也逐渐成熟起来。这套@H_403_9@API的目的是简化开发者对网站性能进行精确分析与控制的过程,方便开发者采取手段提高@H_403_9@web性能。@H_403_9@
整套标准包含了@H_403_9@10余种@H_403_9@API,各自针对性能检测的某个方面。在下图中可以看到它们当前在规范流程中的进展:@H_403_9@
下面是API描述的功能列表@H_403_9@@H_403_9@
有两个使我们必须要关注的:
1.@H_403_9@@H_403_9@页面加载Navigation Timing@H_403_9@@H_403_9@
2.@H_403_9@@H_403_9@页面资源加载Timing:Resource Timing@H_403_9@。@H_403_9@
这两个API@H_403_9@非常有用,可以帮助我们获取页面的Domready@H_403_9@时间、onload@H_403_9@时间、白屏时间等,以及单个页面资源在从发送请求到获取到rsponse@H_403_9@各阶段的性能参数。
使用这两个API@H_403_9@时需要在页面完全加载完成之后才能使用,最简单的办法是在window.onload@H_403_9@事件中读取各种数据,因为很多值必须在页面完全加载之后才能得出。
(1)页面加载Navigation Timing@H_403_9@@H_403_9@@H_403_9@
该对象能够帮助网站开发者检测真实用户数据(RUM),例如带宽、延迟或主页的整体页面加载时间。
打开@H_403_9@chrome浏览器输入:@H_403_9@performance.timing;如下图所示@H_403_9@
返回了一个返回的是一个@H_403_9@PerformanceTiming对象,包含了各种与浏览器性能有关的时间数据,提供浏览器处理网页各个阶段的耗时,它包含的页面性能属性如下表:@H_403_9@
下面有一个图,能更加直观的展示,这些数据直接的关系。@H_403_9@
对我们比较有用的页面性能数据大概包括如下几个:@H_403_9@
DNS查询耗时、@H_403_9@TCP链接耗时、@H_403_9@request请求耗时、解析@H_403_9@dom树耗时、白屏时间、@H_403_9@domready时间、@H_403_9@onload时间等,而这些参数是通过上面的@H_403_9@performance.timing各个属性的差值组成的,计算方法如下:@H_403_9@
DNS查询耗时@H_403_9@:@H_403_9@domainLookupEnd - domainLookupStart@H_403_9@
TCP链接耗时@H_403_9@:@H_403_9@connectEnd - connectStart@H_403_9@
request请求耗时@H_403_9@:@H_403_9@responseEnd - responseStart@H_403_9@
解析@H_403_9@dom树耗时@H_403_9@:@H_403_9@domComplete- domInteractive@H_403_9@
白屏时间@H_403_9@:@H_403_9@responseStart - navigationStart@H_403_9@
domready时间@H_403_9@:@H_403_9@domContentLoadedEventEnd - navigationStart@H_403_9@
onload时间@H_403_9@:@H_403_9@loadEventEnd - navigationStart@H_403_9@
NavigationTiming的目的是用于分析页面整体性能指标。如果要获取个别资源(例如@H_403_9@JS、图片)的性能指标,就需要使用@H_403_9@Resource Timing API。@H_403_9@
@H_403_9@Resource Timing API@H_403_9@@H_403_9@
这个主要用来获取到单个静态资源(@H_403_9@Js,CSS,图片,音频视频等等)从开始发出请求到获取响应之间各个阶段的@H_403_9@Timing
同理在chrome的console输入performance.getEntries();显示了所有静态资源的数组列表;点开后显示了,某一个请求的相关参数有name,type,时间等等。
这个接口是获取所有的资源;同时,该@H_403_9@API还提供了另外另个接口@H_403_9@
performance.getEntriesByName() performance.getEntriesByType()
顾名思义,分别是按资源的名称和类型获取相应的请求数据。@H_403_9@
memory@H_403_9@:浏览器内存情况@H_403_9@@H_403_9@
@H_403_9@
同理输入performance.memory@H_403_9@@H_403_9@@H_403_9@@H_403_9@
@H_403_9@@H_403_9@
jsHeapSizeLimit@H_403_9@
totalJSHeapSize@H_403_9@
usedJSHeapSize @H_403_9@
@H_403_9@注:@H_403_9@usedJSHeapSize@H_403_9@表示所有被使用的@H_403_9@js@H_403_9@堆栈内存;@H_403_9@totalJSHeapSize@H_403_9@表示当前@H_403_9@js@H_403_9@堆栈内存总大小,这表示@H_403_9@usedJSHeapSize@H_403_9@不能大于@H_403_9@totalJSHeapSize@H_403_9@,如果大于,有可能出现了内存泄漏@H_403_9@。@H_403_9@
performance.navigation@H_403_9@对象@H_403_9@@H_403_9@
performance还可以提供一些用户行为信息,主要都存放在@H_403_9@performance.navigation对象上面。@H_403_9@
chrome下如下图:@H_403_9@
(@H_403_9@1)@H_403_9@performance.navigation.type@H_403_9@
该属性返回一个整数值,表示网页的加载来源,可能有以下@H_403_9@4种情况:@H_403_9@
0@H_403_9@:网页通过点击链接、地址栏输入、表单提交、脚本操作等方式加载,相当于常 数@H_403_9@performance.navigation.TYPE_NAVIGATENEXT。@H_403_9@
1@H_403_9@:网页通过@H_403_9@“重新加载@H_403_9@”按钮或者@H_403_9@location.reload()方法加载,相当于常 数@H_403_9@performance.navigation.TYPE_RELOAD。@H_403_9@
2@H_403_9@:网页通过@H_403_9@“@H_403_9@前进@H_403_9@”@H_403_9@或@H_403_9@“@H_403_9@后退@H_403_9@”@H_403_9@按钮加载,相当于常 数@H_403_9@performance.navigation.TYPE_BACK_FORWARD@H_403_9@。@H_403_9@
255@H_403_9@:任何其他来源的加载,相当于常数@H_403_9@performance.navigation.TYPE_UNDEFINED。@H_403_9@
(@H_403_9@2)@H_403_9@performance.navigation.redirectCount@H_403_9@
最后呢,自己写了一段js来测试了上面的相关参数,代码如下:
(function(w){ varresultObj={}; //初始化相关 functionTestTiming(timing){ vartimerArr=[]; vardnsTimer={key:"DNS查询耗时",value:timing.domainLookupEnd-timing.domainLookupStart+"ms"}; vartcpTimer={key:"TCP链接耗时",value:timing.connectEnd-timing.connectStart+"ms"}; varrequestTimer={key:"request请求耗时",value:timing.responseEnd-timing.responseStart+"ms"}; vardomTimer={key:"解析dom树耗时",value:timing.domComplete-timing.domInteractive+"ms"}; varpageEmptyTimer={key:"白屏时间",value:timing.responseStart-timing.navigationStart+"ms"}; vardomReadyTimer={key:"domready时间",value:timing.domContentLoadedEventEnd-timing.navigationStart+"ms"}; varonloadTimer={key:"onload时间",value:timing.loadEventEnd-timing.navigationStart+"ms"}; timerArr=timerArr.concat(dnsTimer,tcpTimer,requestTimer,domTimer,pageEmptyTimer,domReadyTimer,onloadTimer); returntimerArr; } //请求的各种资源(js,图片,样式等) functionTestResource(resourcesObj){ varresourceArr=[]; varlen=resourcesObj.length; for(vari=len-1;i>0;i--){ vartemp={}; varcur=resourcesObj[i]; temp.key=cur.name; temp.resValue=cur.responseEnd-cur.requestStart+"ms"; temp.conValue=cur.connectEnd-cur.connectStart+"ms"; resourceArr.push(temp); } returnresourceArr; } //页面的加载方式 functionpageLoadMethod(type){ vararr=[]; varloadMethod={}; loadMethod.name="进入页面的方式"; varstr=""; switch(type){ case0: str='点击链接、地址栏输入、表单提交、脚本操作等方式加载'; break; case1: str='通过“重新加载”按钮或者location.reload()方法加载'; break; case2: str='网页通过“前进”或“后退”按钮加载'; break; default: str='任何其他来源的加载'; break; } loadMethod.value=str; arr.push(loadMethod); returnarr; } //输出性能数据 functionoutPutData(perObj){ vartimerArr=TestTiming(perObj.timing); varresourcesArr=TestResource(perObj.getEntries()); varloadMethodArr=pageLoadMethod(perObj.navigation.type); console.log("-------页面初始化------------------------"); console.table(timerArr); console.log("-------页面请求------------------------"); console.table(resourcesArr); console.log("-------页面加载方式------------------------"); console.table(loadMethodArr); } w.perTestResult=outPutData; })(window);
说在最后@H_403_9@@H_403_9@
@H_403_9@相关资料@H_403_9@@H_403_9@:@H_403_9@@H_403_9@
1 http://segmentfault.com/a/1190000004010453
@H_403_9@
2 https://github.com/fredshare/blog/issues/5@H_403_9@
3 http://javascript.ruanyifeng.com/bom/performance.html#toc5@H_403_9@