performance的资源计时统计

以下内容原文来自:
http://www.stevesouders.com/blog/2014/08/21/resource-timing-practical-tips/
http://www.stevesouders.com/blog/2014/11/25/serious-confusion-with-resource-timing/

按照自己的理解,做了整理。

一、基本定义:
1. 示例图:


performance的资源计时统计_第1张图片

2. 各个时间段的获取:
	// Navigation Timing
	var t = performance.timing,
	    pageloadtime = t.loadEventStart - t.navigationStart,
	    dns = t.domainLookupEnd - t.domainLookupStart,
	    tcp = t.connectEnd - t.connectStart,
	    ttfb = t.responseStart - t.navigationStart;

	// Resource Timing
	var r0 = performance.getEntriesByType("resource")[0],
	    loadtime = r0.duration,
	    dns = r0.domainLookupEnd - r0.domainLookupStart,
	    tcp = r0.connectEnd - r0.connectStart,
	    ttfb = r0.responseStart - r0.startTime;

3. 使用 getEntriesByType(“resource”) 而不是 getEntries().

getEntries 理论上可以有4种不同类型的返回: “resource”, “navigation”, “mark”, and “measure”。
尽管在当前浏览器的实现中,getEntriesByType(“resource”) 与 getEntries 是暂时一致的。
但为了安全起见,使用前者总是明确的。

4.注意secureConnectionStart不同取值:

    1)undefined: IE浏览器下,该值不可用。见:http://msdn.microsoft.com/en-us/library/windows/desktop/aa383630(v=vs.85).aspx
    2)0: HTTP协议下;
    3)有值(时间戳): HTTPS协议下。(与页面本身是否采用HTTPS协议无关。)

    因此,在使用该属性时候,记得先检查是否有值。例如:
    	var r0 = performance.getEntriesByType("resource")[0];
		if ( r0.secureConnectionStart ) {
		    var ssl = r0.connectEnd - r0.secureConnectionStart;
		}


二、跨域的问题
受同源策略影响,跨域资源获取到的时间点,通常为0.包括以下属性:
    redirectStart
    redirectEnd
    domainLookupStart
    domainLookupEnd
    connectStart
    connectEnd
    secureConnectionStart
    requestStart
    responseStart

    解决的方式是:
    资源响应头,添加  Timing-Allow-Origin 的配置。例如:Timing-Allow-Origin:*
    例如:
http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js

所以,测量时间时候,最好是加个判断:
		// Resource Timing
		var r0 = performance.getEntriesByType("resource")[0],
		    loadtime = r0.duration;
		if ( r0.requestStart ) {
		    var dns = r0.domainLookupEnd - r0.domainLookupStart,
		        tcp = r0.connectEnd - r0.connectStart,
		        ttfb = r0.responseStart - r0.startTime;
		}
		if ( r0.secureConnectionStart ) {
		    var ssl = r0.connectEnd - r0.secureConnectionStart;
		}


三、耗时为零是怎么回事?

1. 由于浏览器会缓存域名的解析,所以, domainLookupStart - domainLookupEnd 很有可能为0.
2. TCP链接是可以重用的(通常服务器和浏览器之间,可以同时保留6左右的活跃链接,具体视情况而定),
所以,connectEnd – connectStart 也有可能为0。同样的,适用于 connectEnd – secureConnectionStart = 0 的情况。

四、304响应的问题

Chrome v36还有IE10/11,当一个跨域资源(已经设置Timing-Allow-Origin)被下载后,如果重新刷新页面,由于浏览器缓存策略,这些资源有可能会返回304响应。
但是,这一次的304响应,浏览器无法正确获得缓存的Timing-Allow-Origin头部设置,从而把它认作“非法”的请求,导致出现前面提到的跨域限制,各个时间点时间为0的情况。
显然,这就导影响了测量值的准确性,得到的时延结果,有可能更高(把304视为200)或更低(把304忽略掉)。


五、最后,duration = responseEnd - redirectStart 得到的结果,有可能不是正确的。为什么?
通过浏览器测试发现,实际情况是: duration = responseEnd - redirectStart + 资源阻塞时间。
所谓 资源阻塞时间,这里指的是,由于浏览器的并发请求是有限的,通常是6~12个,在浏览器开始解析标签(如IMG),并发起请求开始,计时就已经开始了。
而在并发之外,处于等待状态的资源,得到的duration就需要比前面的资源,多出了这个阻塞(排队)的时间。从而,这个duration,就不能很好的测量浏览器到服务器直接的请求了。

示例:http://stevesouders.com/tests/rt-blocking.php  在这个页面中,会发现后面的图片加载,比前面的图片加载,要多出1~2s的时间,而这个时间,就是资源在浏览器排队阻塞的时间了。

六:可以顺便关注一下这个统计脚本:boomerang

https://github.com/lognormal/boomerang
前身是Yahoo出的,它有个插件:https://github.com/lognormal/boomerang/blob/master/plugins/restiming.js,
就基本帮我们完成一些时间点的收集功能。

附录:

测试例子:http://stevesouders.com/tests/tao.php

原文:http://www.stevesouders.com/blog/2014/08/21/resource-timing-practical-tips/
 http://www.stevesouders.com/blog/2014/11/25/serious-confusion-with-resource-timing/

你可能感兴趣的:(JavaScript,html5,performance,timing)