Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

window.performance 详解 #5

Open
fredshare opened this issue Oct 27, 2014 · 30 comments
Open

window.performance 详解 #5

fredshare opened this issue Oct 27, 2014 · 30 comments
Assignees
Labels

Comments

@fredshare
Copy link
Owner

window.performance详解

performance的作用

浏览器暴露给js的一个接口,可以通过这个接口查看用户访问网站的连接建立时间、dns时间等信息。使用该api时需要在页面完全加载完成之后才能使用,最简单的办法是在window.onload事件中读取各种数据,因为很多值必须在页面完全加载之后才能得出。

浏览器支持情况

IE9和chrome6以上的版本都支持:

  • pc端
  • window.performance : ie9
  • window.webkitPerformance : chrome6-9
  • window.performance : chrome10+
  • 移动端
  • android4.0

各个值的详细含义

img
可以看到api的接口定义如下:

memory:浏览器内存情况

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

navigation :网页导航相关

  1. redirectCount:重定向属性
    一个只读属性,返回当前页面是几次重定向才过来的。但是这个接口有同源策略限制,即仅能检测同源的重定向。
  2. type
    返回值应该是0,1,2 中的一个。分别对应三个枚举值:

    0 : TYPE_NAVIGATE (用户通过常规导航方式访问页面,比如点一个链接,或者一般的get方式)

    1 : TYPE_RELOAD (用户通过刷新,包括JS调用刷新接口等方式访问页面)

    2 : TYPE_BACK_FORWARD (用户通过后退按钮访问本页面)

timing :测速相关

img

navigationStart:准备加载新页面的起始时间
redirectStart:如果发生了HTTP重定向,并且从导航开始,中间的每次重定向,都和当前文档同域的话,就返回开始重定向的timing.fetchStart的值。其他情况,则返回0
redirectEnd:如果发生了HTTP重定向,并且从导航开始,中间的每次重定向,都和当前文档同域的话,就返回最后一次重定向,接收到最后一个字节数据后的那个时间.其他情况则返回0
fetchStart:如果一个新的资源获取被发起,则 fetchStart必须返回用户代理开始检查其相关缓存的那个时间,其他情况则返回开始获取该资源的时间
domainLookupStart:返回用户代理对当前文档所属域进行DNS查询开始的时间。如果此请求没有DNS查询过程,如长连接,资源cache,甚至是本地资源等。 那么就返回 fetchStart的值
domainLookupEnd:返回用户代理对结束对当前文档所属域进行DNS查询的时间。如果此请求没有DNS查询过程,如长连接,资源cache,甚至是本地资源等。那么就返回 fetchStart的值
connectStart:返回用户代理向服务器服务器请求文档,开始建立连接的那个时间,如果此连接是一个长连接,又或者直接从缓存中获取资源(即没有与服务器建立连接)。则返回domainLookupEnd的值
(secureConnectionStart):可选特性。用户代理如果没有对应的东东,就要把这个设置为undefined。如果有这个东东,并且是HTTPS协议,那么就要返回开始SSL握手的那个时间。 如果不是HTTPS, 那么就返回0
connectEnd:返回用户代理向服务器服务器请求文档,建立连接成功后的那个时间,如果此连接是一个长连接,又或者直接从缓存中获取资源(即没有与服务器建立连接)。则返回domainLookupEnd的值
requestStart:返回从服务器、缓存、本地资源等,开始请求文档的时间
responseStart:返回用户代理从服务器、缓存、本地资源中,接收到第一个字节数据的时间
responseEnd:返回用户代理接收到最后一个字符的时间,和当前连接被关闭的时间中,更早的那个。同样,文档可能来自服务器、缓存、或本地资源
domLoading:返回用户代理把其文档的 "current document readiness" 设置为 "loading"的时候
domInteractive:返回用户代理把其文档的 "current document readiness" 设置为 "interactive"的时候.
domContentLoadedEventStart:返回文档发生 DOMContentLoaded事件的时间
domContentLoadedEventEnd:文档的DOMContentLoaded 事件的结束时间
domComplete:返回用户代理把其文档的 "current document readiness" 设置为 "complete"的时候
loadEventStart:文档触发load事件的时间。如果load事件没有触发,那么该接口就返回0
loadEventEnd:文档触发load事件结束后的时间。如果load事件没有触发,那么该接口就返回0

组合值的意义

DNS查询耗时 :domainLookupEnd - domainLookupStart
TCP链接耗时 :connectEnd - connectStart
request请求耗时 :responseEnd - responseStart
解析dom树耗时 : domComplete - domInteractive
白屏时间 :responseStart - navigationStart
domready时间 :domContentLoadedEventEnd - navigationStart
onload时间 :loadEventEnd - navigationStart

performance.getEntries 资源测速

img
比如图中type为img的图片整个加载时间为duration ms。
可以通过这个接口统计整个页面有多少img、css、js以及对应的下载时间等信息。

常用统计方法

performance 测速上报

     /**
 * 上报Performance timing数据;
 * 如果某个时间点花费时间为0,则此时间点数据不上报。
 * @param {String}
 *            f1 flag1简写,测速系统中的业务ID,譬如校友业务为164
 * @param {String}
 *            f2 flag2简写,测速的站点ID
 * @param {String}
 *            f3_ie flag3简写,测速的页面ID
 *(因为使用过程中我们发现IE9的某些数据存在异常,
 * 如果IE9和chrome合并统计,会影响分析结果,所以这里建议分开统计)
 * @param {String}
 *            f3_c flag3简写,测速的页面ID
 * (如果为空,则IE9和chrome合并统计)
 */
function setTimingRpt(f1, f2, f3_ie, f3_c){     
    var _t, _p = (window.webkitPerformance ? window.webkitPerformance : window.msPerformance), _ta = ["navigationStart","unloadEventStart","unloadEventEnd","redirectStart","redirectEnd","fetchStart","domainLookupStart","domainLookupEnd","connectStart","connectEnd","requestStart",/*10*/"responseStart","responseEnd","domLoading","domInteractive","domContentLoadedEventStart","domContentLoadedEventEnd","domComplete","loadEventStart","loadEventEnd"], _da = [], _t0, _tmp, f3 = f3_ie;  
    _p = (_p ? _p : window.performance);        
    if (_p && (_t = _p.timing)) {       
        if (!_t.domContentLoadedEventStart) {
            _ta.splice(15, 2, 'domContentLoaded', 'domContentLoaded');
        } else {
            if (f3_c) {
                f3 = f3_c;
            }
        }           
        _t0 = _t[_ta[0]];
        for (var i = 1, l = _ta.length; i < l; i++) {
            _tmp = _t[_ta[i]];
            _tmp = (_tmp ? (_tmp - _t0) : 0);
            if (_tmp > 0) {
                _da.push( i + '=' + _tmp);
            }
        }           
        if (window.d0) {//统计页面初始化时的d0时间
            _da.push('30=' + (window.d0 - _t0));
        }           
        var url = 'http://www.report.com?flag1=' + f1 + '&flag2=' + f2 + '&flag3=' + f3 + '&' + _da.join('&');      
        var _img = new Image();
        setTimeout(function(){
            _img.src = url;
        }, 10);
    }       
};
//注意!需要在onload事件后进行计算上报。
window.onload = function(){
    setTimingRpt(7839, 7, 3);//活动页面
};

performance chrome可视化插件

performance chrome可视化插件

未完待续!!
参考:

HTML5 performance API 草案
Resource Timing

@fredshare fredshare added the blog label Oct 27, 2014
@fredshare fredshare self-assigned this Oct 27, 2014
@hehongwei44
Copy link

相当不错

@fredshare
Copy link
Owner Author

@hehongwei44 多谢支持~~

@hehongwei44
Copy link

用在实际项目中了嘛 稳定性怎么样

@fredshare
Copy link
Owner Author

@hehongwei44 实际测速就是用performance接口的,移动端支持度在40~60%左右。

@hehongwei44
Copy link

我也是用performance对像来上报的,不过没有你封装的优雅

@hehongwei44
Copy link

还请教你一个问题,不支持performance对象的浏览器 怎么做上报的。腾讯是怎么做的呢?@fredshare

@fredshare
Copy link
Owner Author

不支持performance的情况下,我们做了domready、onload、白屏时间等的统计,通过埋点的方式进行计算统计,比如domready,head最前面埋一个点,html尾部卖一个点,两个之间的差值大约等于domready时间;onload就是用DOMContentLoaded触发的时候打点等。
我记得还有多普勒测速,这个是在performance标准出来之前很多公司有使用到的方案。

@hehongwei44
Copy link

有写地方没太明白,setTimingRpt中的f1,f2,f3_ie,f3_c 具体指的是什么?我只是把_da上传服务器接口,你的那些参数是不是对我作用不大?

@hehongwei44
Copy link

还有个问题就是,你的_da参数得到的值都是与navigationStart的差值,比如我要得到“解析dom树耗时”,但是_da没有提供,你们是不是后台对其进行了处理。

@fredshare
Copy link
Owner Author

image
哦,这个涉及到上报系统的数据结构定义,可能一个业务下有多个站点,每个站点下有不少页面,需要针对每一个业务、站点、页面分别申请不一样的id来区别

@fredshare
Copy link
Owner Author

@hehongwei44 这个demo中的函数是一个标准的上报performance接口的函数
如果需要上报比如dom树解析耗时,你需要前端算出dom树解析,然后上报。计算方法:
image

@hehongwei44
Copy link

哦 我了解了,不过你上传页面的URL应该也可以做到区分是哪个页面的上报吧,只是你们自己对齐封装了吧。

@fredshare
Copy link
Owner Author

@hehongwei44 是的,前端封装好了,后台来区分比较麻烦,需要维护一大堆map对应表

@hehongwei44
Copy link

哦 我了解了,因为你我的业务场景不一样,你的函数看样子,我不能直接拿上就用。自己还得在你的代码上做一层封装。

@hehongwei44
Copy link

if (!_t.domContentLoadedEventStart) {
_ta.splice(15, 2, 'domContentLoaded', 'domContentLoaded');
} else {
if (f3_c) {
f3 = f3_c;
}
}
你这段代码的意图是什么?

@fredshare
Copy link
Owner Author

@hehongwei44
image

@hehongwei44
Copy link

能说说异常出现的原因嘛

@fredshare
Copy link
Owner Author

@hehongwei44 你可以看看这个http://www.cnblogs.com/_franky/archive/2011/11/07/2238980.html 上面有详细的解释

@ywang1724
Copy link

关于其中几项值的计算方法有些疑问,麻烦楼主解答
1、request请求耗时 :responseEnd - responseStart
是否应该为responseEnd - requestStart?
2、白屏时间 :responseStart - navigationStart
responseStart 是开始接收响应的时间,白屏时间是指页面开始出现内容的时间,这两个时间是否是一样的?

@zlzdp
Copy link

zlzdp commented Nov 25, 2015

mark

@chua1989
Copy link

@ywang1724 所以说白屏时间计算的不对,白屏时间=开始渲染时间(首字节时间+HTML下载完成时间)+头部资源加载时间;对应的应该是白屏时间=domLoading - navigationStart +头部资源加载时间;头部资源加载时间还是要自己算

@zhujun24
Copy link

loadEventEnd:文档触发 load事件结束后 的时间。如果load事件没有触发,那么该接口就返回0。所以在onload 里计算这个是不是会出问题?

@hellozhangran
Copy link

request请求耗时 :responseEnd - responseStart
这一条我不太理解,尤其是responseEnd这个时间点。
responseEnd指的是服务器返回最后一个字节的时间!那这最后一个字节指的是什么呢?
如果请求一个html页面,那最后一个字节指的是html页面返回完毕?还是里面的js、css返回完毕。。。如果是的话,responseEnd - responseStart 应该是下载时间了吧,怎么只是请求时间呢??

@zqs-zjj-1208
Copy link

大神 ,你好。敢问如何测试监控移动端设备呢?没写过js,不知道怎么弄,望百忙之中指点一二,多谢!!!

@reaperme
Copy link

reaperme commented Mar 6, 2018

你这里的白屏时间计算是错误的,没有包括头部资源加载的时间

@fredshare
Copy link
Owner Author

@reaperme ,在responseStart开始的时候,页面就开始渲染了。

@fredshare
Copy link
Owner Author

@zqs-zjj-1208 移动端监控是一样的,移动端也有performance接口

@fredshare
Copy link
Owner Author

@hellozhangran 这里的请求耗时指的是从发起请求到请求结束的时间

@junbinxu
Copy link

您好,请问怎么获取每个资源的waiting time ?

@moozeeli
Copy link

图片看不到了,是我网络的问题吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests