使用window.performance分析web前端性能

http://shuizhongyue.blog.51cto.com/7439523/1718327
版权声明:原创作品,如需转载,请与作者联系。否则将追究法律责任。

说在前面

 

最近身体出了点问题,折腾了个把星期总算活过来。差不多个把星期没写博客了,今天分享一个比较好玩的东东—performance

上一篇博客中分享了很多页面性能的测试工具,通常,页面的性能问题也是我们开发中一个重要环节,但一直以来我们也没有没有比较好的手段,来检测页面的性能;通常,我们只能以来与chrome或者FF浏览器自带的profile,timming或者使用在线的pagetest,阿里测等。我们很希望有一套页面性能的api,我们可以自己编写代码测试页面性能而不需要借助于其他的工具。

好在W3C Web性能工作小组已经

与各浏览器厂商都已认识到性能对于web开发的重要性,为了解决当前性能测试的困难,W3C推出了一套性能API标准,各种浏览器对这套标准的支持如今也逐渐成熟起来。这套API的目的是简化开发者对网站性能进行精确分析与控制的过程,方便开发者采取手段提高web性能。

 


正文

整套标准包含了10余种API,各自针对性能检测的某个方面。在下图中可以看到它们当前在规范流程中的进展:

wKioL1ZcSTXiPaqbAACkT1e8UQg360.png

 


下面是API描述的功能列表

 

wKiom1ZcSW3B0mRnAAWjIzkO6x8472.jpg

 


浏览器支持情况

wKiom1ZcSfaAialBAAJmZgOoup4070.jpg

有两个使我们必须要关注的:

1.     页面加载Navigation Timing

2.     页面资源加载Timing: Resource Timing。

这两个API非常有用,可以帮助我们获取页面的Domready时间、onload时间、白屏时间等,以及单个页面资源在从发送请求到获取到rsponse各阶段的性能参数。

使用这两个API时需要在页面完全加载完成之后才能使用,最简单的办法是在window.onload事件中读取各种数据,因为很多值必须在页面完全加载之后才能得出。

 


(1)页面加载Navigation Timing

    该对象能够帮助网站开发者检测真实用户数据(RUM),例如带宽、延迟或主页的整体页面加载时间。

打开chrome浏览器输入:performance.timing;如下图所示

wKiom1ZcSpmguSzrAAKxHjnHb-U768.jpg

返回了一个返回的是一个PerformanceTiming对象,包含了各种与浏览器性能有关的时间数据,提供浏览器处理网页各个阶段的耗时,它包含的页面性能属性如下表:

wKiom1ZcTF2CG3WzAAd0uSIn4aM329.jpg

下面有一个图,能更加直观的展示,这些数据直接的关系。

wKioL1ZcTOOArNNrAABqmp7zgc8825.png

对我们比较有用的页面性能数据大概包括如下几个:

DNS查询耗时、TCP链接耗时、request请求耗时、解析dom树耗时、白屏时间、domready时间、onload时间等,而这些参数是通过上面的performance.timing各个属性的差值组成的,计算方法如下:

DNS查询耗时 :domainLookupEnd - domainLookupStart

TCP链接耗时 :connectEnd - connectStart

request请求耗时 :responseEnd - responseStart

解析dom树耗时 : domComplete- domInteractive

白屏时间 :responseStart - navigationStart

domready时间 :domContentLoadedEventEnd - navigationStart

onload时间 :loadEventEnd - navigationStart

NavigationTiming的目的是用于分析页面整体性能指标。如果要获取个别资源(例如JS、图片)的性能指标,就需要使用Resource Timing API。


Resource Timing API

这个主要用来获取到单个静态资源(Js,CSS,图片,音频视频等等)从开始发出请求到获取响应之间各个阶段的Timing

同理在chrome的console输入performance.getEntries();显示了所有静态资源的数组列表;点开后显示了,某一个请求的相关参数有name,type,时间等等。

wKiom1ZcTPKANgZOAAKDheEoLnQ143.jpg

这个接口是获取所有的资源;同时,该API还提供了另外另个接口

1
2
performance.getEntriesByName()
performance.getEntriesByType()

顾名思义,分别是按资源的名称和类型获取相应的请求数据。


memory:浏览器内存情况

同理输入performance.memory

wKioL1ZcTv-wN7zcAABvTtHebW4704.jpg

  1. jsHeapSizeLimit

  2. totalJSHeapSize

  3. usedJSHeapSize    

    注:usedJSHeapSize表示所有被使用的js堆栈内存;totalJSHeapSize表示当前js堆栈内存总大小,这表示usedJSHeapSize不能大于totalJSHeapSize,如果大于,有可能出现了内存泄漏

 

 


performance.navigation对象

performance还可以提供一些用户行为信息,主要都存放在performance.navigation对象上面。

chrome下如下图:

wKioL1ZcT-ji-vIvAAEzP5CJrvA246.jpg

这个对象有两个属性:

(1)performance.navigation.type

该属性返回一个整数值,表示网页的加载来源,可能有以下4种情况:

0:网页通过点击链接、地址栏输入、表单提交、脚本操作等方式加载,相当于常                        数performance.navigation.TYPE_NAVIGATENEXT。

1:网页通过“重新加载”按钮或者location.reload()方法加载,相当于常                       数performance.navigation.TYPE_RELOAD。

2:网页通过“前进”或“后退”按钮加载,相当于常         数performance.navigation.TYPE_BACK_FORWARD。

255:任何其他来源的加载,相当于常数performance.navigation.TYPE_UNDEFINED。

(2)performance.navigation.redirectCount

表示当前网页经过了多少次重定向跳转。


最后呢,自己写了一段js来测试了上面的相关参数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
(function(w){
    var resultObj = {};
    //初始化相关
    function TestTiming(timing){
        var timerArr = [];
        var dnsTimer = {key:"DNS查询耗时" , value:timing.domainLookupEnd - timing.domainLookupStart + "ms"};
        var tcpTimer = {key:"TCP链接耗时" , value:timing.connectEnd - timing.connectStart + "ms"};
        var requestTimer = {key:"request请求耗时" , value:timing.responseEnd - timing.responseStart + "ms"};
        var domTimer = {key:"解析dom树耗时" , value:timing.domComplete - timing.domInteractive + "ms"};
        var pageEmptyTimer = {key:"白屏时间" , value:timing.responseStart - timing.navigationStart + "ms"};
        var domReadyTimer = {key:"domready时间" , value:timing.domContentLoadedEventEnd - timing.navigationStart + "ms"};
        var onloadTimer = {key:"onload时间" , value:timing.loadEventEnd - timing.navigationStart + "ms"};
 
        timerArr = timerArr.concat(dnsTimer, tcpTimer, requestTimer, domTimer, pageEmptyTimer, domReadyTimer, onloadTimer);
        return timerArr;
    }
    //请求的各种资源(js,图片,样式等)
    function TestResource(resourcesObj){
        var resourceArr = [];
        var len = resourcesObj.length;
        for(var i = len - 1;i >0;i--){
            var temp = {};
            var cur = resourcesObj[i];
            temp.key = cur.name;
            temp.resValue = cur.responseEnd - cur.requestStart + "ms";
            temp.conValue = cur.connectEnd - cur.connectStart + "ms";
            resourceArr.push(temp);
        }
        return resourceArr;
    }
    //页面的加载方式
    function pageLoadMethod(type){
        var arr = [];
        var loadMethod = {};
        loadMethod.name = "进入页面的方式";
        var str = "";
        switch(type){
            case 0:
                str = '点击链接、地址栏输入、表单提交、脚本操作等方式加载';
                break;
            case 1:
                str = '通过“重新加载”按钮或者location.reload()方法加载';
                break;
            case 2:
                str = '网页通过“前进”或“后退”按钮加载';
                break;
            default:
                str = '任何其他来源的加载';
                break;
        }
        loadMethod.value = str;
        arr.push(loadMethod);
        return arr;
    }
    //输出性能数据
    function outPutData(perObj){
        var timerArr = TestTiming(perObj.timing);
        var resourcesArr = TestResource(perObj.getEntries());
        var loadMethodArr = pageLoadMethod(perObj.navigation.type);
        console.log("-------页面初始化------------------------");
        console.table(timerArr);
        console.log("-------页面请求------------------------");
        console.table(resourcesArr);
        console.log("-------页面加载方式------------------------");
        console.table(loadMethodArr);
    }
 
    w.perTestResult = outPutData;
})(window);

说在最后

相关资料

1  http://segmentfault.com/a/1190000004010453

2  https://github.com/fredshare/blog/issues/5

3  http://javascript.ruanyifeng.com/bom/performance.html#toc5

本文出自 “shuizhongyue” 博客,转载请与作者联系!

posted @ 2017-09-02 16:10  五艺  阅读(444)  评论(0)    收藏  举报