HTML5的學習--performance

HTML5提供的performance接口精確的告訴咱們當訪問一個網站頁面時當前網頁每一個處理階段的精確時間(timestamp),以方便咱們進行前端分析。css

它是瀏覽器的直接實現,比在網頁中用js設置Date.time或者cookie來分析網頁時間上要精確不少。html

支持瀏覽器: IE9+,Chrome11+,Firefox7+.前端

如下是w3c提供的performance.timing各階段api圖html5

成員:web

.navigation (一個叫作performanceNavigation的對象.)chrome

.timing (這是一個被稱做performanceTiming的包含了不少成員的對象) api

 

PS:瀏覽器

1. performance,僅能對當前的html文檔作檢測,全部的對象都和當前文檔有關。若是咱們想檢測某個圖片資源的網絡情況,則不行。 好比咱們想監控,用戶訪問咱們服務的情況,就只能建立一個iframe,url爲咱們服務某個地址(除非用戶訪問的當前頁,就是咱們要監控的對象)。而後才能夠監控此次一次請求的網絡狀態等等。因此建議若是能夠考慮使用performance作監控,則須要有抽樣、時間點等監控機制。不然給服務器帶來額外壓力,得不償失。若是要監控其餘資源,須要使用 ResourceTiming。 緩存

 

performanceNavigation(performance.navigation)對象的成員服務器

performanceNavigation.type 

返回值應該是0,1,2 中的一個.分別對應三個枚舉值:

0 : TYPE_NAVIGATE  (用戶經過常規導航方式訪問頁面,好比點一個連接,或者通常的get方式.)

1 : TYPE_RELOAD  (用戶經過刷新,包括JS調用刷新接口等方式訪問頁面)

2 : TYPE_BACK_FORWARD (用戶經過後退按鈕訪問本頁面)

ps:草案中其實還有 3 : TYPE_RESERVED (保留,其餘非前三種方式訪問.)

 

performanceNavigation.redirectCount

一個只讀屬性,返回當前頁面是幾回重定向纔過來的。可是這個接口有同源策略限制,即僅能檢測同源的重定向。

bugs:

  1. IE9,當一個同源的頁面a鏈接到地址b(是否於a,c同源都如此),後被重定向到同源頁面c時,navigation.redirectCount竟然會是1。而不是0,此bug已被IE10 PP2修復。

 

performanceTiming(performance.timing)對象的成員:

.navigationStart 

瀏覽器完成卸載前一個文檔的時間(也就是準備加載新頁面的那個起始時間)。若是沒有前一個文檔,那麼就返回 timing.fetchStart的值。

彷佛只有Chrome 很是嚴格遵照了此草案。 即不把刷新頁面,以及一個標籤頁輸入地址到指定頁面,視爲發生文檔的卸載。

bugs:

     1. IE9,當發生重定向時.navigationStart 會是0。IE10 PP2 已修復此問題.

     2. IE9-IE10 PP2,的一個問題是刷新當前頁面,或在某個標籤頁輸入地址爲非相同頁面時,會被視爲存在前一個文檔,也就是說,其navigationStart會早於fetchStart。(除非在當前頁再次輸入地址按回車。再次進入該頁面,則被視爲無前一個文檔被卸載)。而實際上這時候navigationStart,是unloadEventEnd的時間。

     3. Firefox7-Firefox10,一個新標籤頁也會被視爲一個有效的文檔。因此這時候,會有值,且不是fetchStart的值。

.unloadEventStart

若是前一個文檔,和當前文檔同源,返回前一個文檔發生unload事件前的時間.若是沒有前一個文檔,或不一樣源,則返回0.

bugs:

     1. IE9-IE10 pp2,Chrome17-,在前一個文檔與當前文檔中間發生重定向時, 且先後兩個文檔同源時, unloadEventStart,也會返回0

.unloadEventEnd

若是前一個文檔和當前文檔同源.返回前一個文檔發生unload事件的時間. 若是沒有前一個文檔,或不一樣源,則返回0。

若是,發生了HTTP重定向,或者相似的事情。而且,從導航開始中間的每次重定向,並不都和當前文檔同域的話,則返回0。

bugs:

     1. IE9-IE10 pp2,Chrome17-,在前一個文檔與當前文檔中間發生重定向時,且先後兩個文檔同源時,unloadEventEnd也會返回0。

.redirectStart

若是,發生了HTTP重定向,或者相似的事情。而且,從導航開始,中間的每次重定向,都和當前文檔同域的話,就返回開始重定向的,timing.fetchStart的值。其餘狀況,則返回0。

bugs:

     1. IE9-IE10 pp2,在頁面a,連接到地址b,並重定向到與b同源的頁面c時。redirectStart,將爲0.即同源策略,竟然會考慮導航頁。

.redirectEnd

若是,發生了HTTP重定向,或者相似的事情.而且,從導航開始,中間的每次重定向,都和當前文檔同域的話,就返回最後一次重定向,接收到最後一個字節數據後的那個時間.其餘狀況則返回0.

bugs:

     1. IE9-IE10 pp2,在頁面a,連接到地址b,並重定向到與b同源的頁面c時. redirectSEnd,將爲0.即同源策略,竟然會考慮導航頁.

.fetchStart

若是一個新的資源(這裏是指當前文檔)獲取被髮起,或相似的事情發生,則 fetchStart必須返回用戶代理開始檢查其相關緩存的那個時間,其餘狀況則返回開始獲取該資源的時間.

.domainLookupStart 

返回用戶代理對當前文檔所屬域進行DNS查詢開始的時間. 若是此請求沒有DNS查詢過程,如長鏈接,資源cache,甚至是本地資源等. 那麼就返回 fetchStart的值.

bugs:

     1. Firefox7-Firefox10,的實現有錯誤. 由於其值,並無遵照標準所描述的對應時間節點.而是默認以navigationStart做爲時間起點,並以中間的重定向時間作累加.而獲得domainLookupStart的時間.即便這個重定向是非同源的重定向.所消耗的時間都會被計算進去. 那麼,這也就解釋了,爲何當沒有重定向發生時, domainLookupStart - fetchStart, 咱們每每會獲得一個負值的緣由,由於navigationStart,是要早於 fetchStart的.

.domainLookupEnd

返回用戶代理對結束對當前文檔所屬域進行DNS查詢的時間.若是此請求沒有DNS查詢過程,如長鏈接,資源cache,甚至是本地資源等. 那麼就返回 fetchStart的值.

bugs:

     1.參考domainLookupStart的bug. End具有相同的問題.

.connectStart

返回用戶代理向服務器服務器請求文檔,開始創建鏈接的那個時間,若是此鏈接是一個長鏈接,又或者直接從緩存中獲取資源(即沒有與服務器創建鏈接).則返回domainLookupEnd的值.

bugs:

     1. Firefox7 當資源走cache,即並未建立鏈接時. connentStart 的值爲0.

     2. Firefox8-Firefox10,當並未建立鏈接時,connetStart的值是fetchStart的值,而不是domainLookEnd的值. 但這裏涉及到一個慣性問題,由於domainLookupEnd的累積時間就已經背離了標準了,因此即便connectStart遵照標準.也是一個有問題的值.

.connectEnd

返回用戶代理向服務器服務器請求文檔,創建鏈接成功後(注意,不是斷開鏈接的時間.)的那個時間.若是此鏈接是一個長鏈接,又或直接從緩存中獲取資源 (即沒有與服務器創建鏈接),則返回domainLookupEnd的值.

bugs:

     參考connectStart的問題.connectEnd具有一樣的問題.

若是鏈接創建失敗,而用戶代理進行重連,則connectStart和connectEnd則應該是此次重連的相關的值.其中connectEnd必須包括創建鏈接的時間以及,SSH握手協議和SOCKS認證等時間.

.secureConnectionStart

可選特性.用戶代理若是沒有對應的東東,就要把這個設置爲undefined.若是有這個東東,而且是HTTPS協議,那麼就要返回開始SSL握手的那個時間. 若是不是HTTPS, 那麼就返回0.

補充:Firefox7-10,IE9-IE10 PP2,都木有實現這個api.因此始終是undefined.

.requestStart

返回從服務器、緩存、本地資源等,開始請求文檔的時間. 

若是請求中途,鏈接斷開了,而且用戶代理進行了重連,並從新請求了資源,那麼requestStart就必須爲這個新請求所對應的時間.

     performance.timing 並不包含一個 單表請求結束的"requestEnd"接口. 緣由有兩點:

          1. 用戶代理所能肯定的請求的結束,並不能表明正確的網絡栓書中的結束時間. 因此設計這個屬性並沒什麼用處.

          2. 一些用戶代理,若是要封裝一個表明HTTP層面的,請求結束時間的接口,成本會很是高昂.

bugs: 
     1. Firefox7,直接走本地緩存時,.requestStart的值將爲0. (Firefox8已修復此問題)

.responseStart

返回用戶代理從服務器、緩存、本地資源中,接收到第一個字節數據的時間.

.responseEnd

返回用戶代理接收到最後一個字符的時間,和當前鏈接被關閉的時間中,更早的那個. 一樣,文檔可能來自服務器、緩存、或本地資源.

補充: 此值的讀取應該是在咱們能夠確保真的是Response結束之後. 好比window.onload.  由於考慮到chunked輸出的狀況. 那麼咱們腳本執行,並獲取該值時,響應尚未結束. 這就會致使獲取時間不許確.

bugs : 
     1. IE10 PP2, 以及Chrome17- ,走本地緩存時.在文檔中間的腳本執行時去讀取此值, 將爲0. IE9原本沒有問題,結果IE10 PP2,反倒有了問題.
     2. Chrome16-,(Chrome17,已修復此問題.)在地址欄輸入相同地址,走本地緩存時. responseEnd的時間,竟然早於responseStart的時間. (不得不認可,這簡直就是奇葩啊!)
     3. Chrome17-,從頁面a,到地址b,再重定向到地址c, 此時若是地址c是走緩存.則. ResponseEnd的時間,會遭遇ResponseStart的時間.(好吧,咱們把但願寄予Chrome18好了.)
實現差別:(因爲草案中,並未說起,當文檔被分段輸出後.在中間文檔數據,接受過程當中,responseEnd應如何處理,致使瀏覽器實現存在差別.)
     IE9 - IE10 PP2 , Firefox8-Firefox10,在不走存在Response階段(非走cache的狀況下.).以接收第一個chunked包結束的時間做爲.responseEnd的時間.(這將致使後續的一系列問題.)
     Chrome17-,Firefox7,則在分段數據的接受過程當中,不會更新.responseEnd的時間,其值,始終爲0.

.domLoading 

返回用戶代理把其文檔的 "current document readiness" 設置爲 "loading"的時候.

(current document readiness 其實就是document.readyState API對應的狀態.)

參考:http://dev.w3.org/html5/spec/dom.html#current-document-readiness

bugs : 
     1. IE9. 在分段輸出文檔的狀況下,該值老是要晚於最終responseEnd的值. 基於responseEnd的IE實現的bug.這也合情合理.
實現差別:
     iE9 - IE10 PP2 , 當文檔是chunked方式輸出的時候.老是要等最後一個chunked被瀏覽器接收後,domLoading纔會有有效值.  也就是說,IE中目前的情況是.domLoading.不管如何,都要晚於responseEnd.其餘瀏覽器則無此問題.  可是這個問題致使咱們計算IE下DOM Parse不許確. 即 domInteractive - domLoading 甚至會常常獲得0. 

.domInteractive

返回用戶代理把其文檔的 "current document readiness" 設置爲 "interactive"的時候.

從標準來講,domReady的狀態爲"interactive"時,意味着,文檔解析結束了. 由於標準中描述, DOM樹建立結束後第一件事,就是把 "current document readiness" 設置爲"interactive"

參考:http://dev.w3.org/html5/spec/the-end.html#the-end 中第一步.

bugs : 
     1. IE9,IE10 PP2 . 在分段輸出文檔的狀況下,該值並非所有文檔解析完成後的時間,而是第一個數據塊被解析完成的時間,基於responseEnd的IE實現的bug.通過向後推定這也合情合理.
實現差別:(因爲草案中,並未說起,文檔解析並未結束時,其默認值的應該是多少.致使瀏覽器實現有差別.)
    按我我的理解,並未解析結束,應該爲0. 可是IE彷佛對這個東西理解不太同樣. 其餘瀏覽器會是0. 可是. IE9-IE10 PP2,則會比較有趣.即便是分段輸出,我取到的值.也和onload之後去到的,domInteractive的值是一致的.  致使這一神奇現象的緣由是,正式IE系的bug所導. 該時間是錯誤的引用了,DOM解析完成第一個數據塊的時間.而不是整個文檔的. 可是糾結起來就要挖掘更深層次的緣由了. 由於草案只說該值體現的是,用戶代理把"current document readiness" 設置爲 "interactive"的時間.若是IE系處理分段輸出的html文檔,向來都是這樣作的。那麼該值與其餘瀏覽器的差別。也是能夠理解的. 

.domContentLoadedEventStart

返回文檔發生 DOMContentLoaded事件的時間.

參考:http://dev.w3.org/html5/spec/the-end.html#the-end  中第4步.
DOMContentLoad和 DOMInteractive 之間差了兩個步驟. 其中之一是, 全部open elements出棧 ,而後去看看 待運行的script list中是否有須要運行的腳本,若是有則執行,一直到這個列表爲空了.再觸發DOMContentLoad.  須要主的是這個待運行腳本列表.有些可能在不一樣瀏覽器中,被加入進去的行爲可能不一樣. 好比 document.write寫入文檔流的腳本,以及script deferr 的腳本.. 因此咱們應該知道deferr的腳本也是要他推遲domContentLoaded的,也就是咱們最經常使用的所謂domReady.(至少html5的規範是如此.)

.domContentLoadedEventEnd

文檔的DOMContentLoaded 事件的結束時間.

補充:所謂事件結束的時間,是指,若是DOMContentLoaded事件被開發者註冊了回調事件.那麼這個時間的End時間減去Start的時間.就會是這個回調執行的大概事件. 固然居於部分瀏覽器實現可能會有2-3ms的偏差. 可是這個時間,基本能夠忽略不計. 相似的狀況還有後面的.loadEventStart,End. 即 window.onload 全部回調所消耗的時間.

.domComplete

返回用戶代理把其文檔的 "current document readiness" 設置爲 "complete"的時候.

PS:若是 current document readiness 的某個狀態被屢次觸發,那麼對應的  domLoading, domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd and domComplete這些對應的API返回的時間,就應該是這個狀態第一次觸發的時間.

.loadEventStart

文檔觸發load事件的時間. 若是load事件沒有觸發,那麼該接口就返回0.

.loadEventEnd

文檔觸發load事件結束後的時間. 若是load事件沒有觸發,那麼該接口就返回0.

external : 另外,我很期待微軟的私有實現,msFirstPaint 的屬性。可以獲得標準的採納...這樣對於監控瀏覽器首次渲染花費的時間.有過重大的意義了。 

Chrome 也有了一些私有支持:

chrome.loadTimes()
 
下面是獲取基本的運行時間信息的代碼
var timing = performance.timing;
var readyStart = timing.fetchStart - timing.navigationStart;
var redirectTime = timing.redirectEnd  - timing.redirectStart;
var appcacheTime = timing.domainLookupStart  - timing.fetchStart;
var unloadEventTime = timing.unloadEventEnd - timing.unloadEventStart;
var lookupDomainTime = timing.domainLookupEnd - timing.domainLookupStart;
var connectTime = timing.connectEnd - timing.connectStart;
var requestTime = timing.responseEnd - timing.requestStart;
var initDomTreeTime = timing.domInteractive - timing.responseEnd;
var domReadyTime = timing.domComplete - timing.domInteractive; //過早獲取時,domComplete有時會是0
var loadEventTime = timing.loadEventEnd - timing.loadEventStart;
var loadTime = timing.loadEventEnd - timing.navigationStart;//過早獲取時,loadEventEnd有時會是0


console.log('準備新頁面時間耗時: ' + readyStart);
console.log('redirect 重定向耗時: ' + redirectTime);
console.log('Appcache 耗時: ' + appcacheTime);
console.log('unload 前文檔耗時: ' + unloadEventTime);
console.log('DNS 查詢耗時: ' + lookupDomainTime);
console.log('TCP鏈接耗時: ' + connectTime);
console.log('request請求耗時: ' + requestTime);
console.log('請求完畢至DOM加載: ' + initDomTreeTime);
console.log('解釋dom樹耗時: ' + domReadyTime);
console.log('load事件耗時: ' + loadEventTime);
console.log('從開始至load總耗時: ' + loadTime);

 

摘自:

http://www.cnblogs.com/_franky/archive/2011/11/07/2238980.html

http://www.th7.cn/web/html-css/201311/14802.shtml

相關文章
相關標籤/搜索