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/

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

[b]一、基本定義:[/b]
1. 示例圖:


[img]http://dl2.iteye.com/upload/attachment/0104/2580/712d9cba-5bf9-354f-9c6e-076585085198.png[/img]

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;
}


[b]二、跨域的問題[/b]
受同源策略影響,跨域資源獲取到的時間點,通常爲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;
}


[b]三、耗時爲零是怎麼回事?[/b]

1. 由於瀏覽器會緩存域名的解析,所以, domainLookupStart - domainLookupEnd 很有可能爲0.
2. TCP鏈接是可以重用的(通常服務器和瀏覽器之間,可以同時保留6左右的活躍鏈接,具體視情況而定),
所以,connectEnd – connectStart 也有可能爲0。同樣的,適用於 connectEnd – secureConnectionStart = 0 的情況。

[b]四、304響應的問題[/b]

Chrome v36還有IE10/11,當一個跨域資源(已經設置Timing-Allow-Origin)被下載後,如果重新刷新頁面,由於瀏覽器緩存策略,這些資源有可能會返回304響應。
但是,這一次的304響應,瀏覽器無法正確獲得緩存的Timing-Allow-Origin頭部設置,從而把它認作“非法”的請求,導致出現前面提到的跨域限制,各個時間點時間爲0的情況。
顯然,這就導影響了測量值的準確性,得到的時延結果,有可能更高(把304視爲200)或更低(把304忽略掉)。


[b]五、最後,duration = responseEnd - redirectStart 得到的結果,有可能不是正確的。爲什麼?[/b]
通過瀏覽器測試發現,實際情況是: duration = responseEnd - redirectStart + 資源阻塞時間。
所謂 資源阻塞時間,這裏指的是,由於瀏覽器的併發請求是有限的,通常是6~12個,在瀏覽器開始解析標籤(如IMG),併發起請求開始,計時就已經開始了。
而在併發之外,處於等待狀態的資源,得到的duration就需要比前面的資源,多出了這個阻塞(排隊)的時間。從而,這個duration,就不能很好的測量瀏覽器到服務器直接的請求了。

示例:http://stevesouders.com/tests/rt-blocking.php  在這個頁面中,會發現後面的圖片加載,比前面的圖片加載,要多出1~2s的時間,而這個時間,就是資源在瀏覽器排隊阻塞的時間了。
[b]
六:可以順便關注一下這個統計腳本:boomerang[/b]
https://github.com/lognormal/boomerang
前身是Yahoo出的,它有個插件:https://github.com/lognormal/boomerang/blob/master/plugins/restiming.js,
就基本幫我們完成一些時間點的收集功能。

[b]附錄:[/b]

測試例子: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/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章