我們總希望網頁加載的快一點。谷歌實驗顯示短如100毫秒的延遲就會對用戶體驗造成不好的影響。那么我們如何來測量網頁加載速度?"page load"的真實含義又是什么?
Navigation Timing 是一個可以在web中精確測量性能的javascript API。這個API提供了一個簡單的方法來獲得頁面導航、加載事件的精確而又詳細的時間狀態。目前在 IE9、Chrome、Firefox nightly builds 中可用。
這篇文章描述了 Navigation API 並展示了如何使用API導出時間數據。
使用方法:
在Chrome中打開控制台,在命令行中輸入performance,點開並查看它的timing屬性,你會看到如下代碼:

如果在IE中使用,需要使用<!doctype html>文檔聲明,瀏覽器需要在標准模式下。
各屬性代表的意義:
每一個performance.timing屬性都表示一個頁面事件(例如頁面發送了請求)或者頁面加載(例如當DOM開始加載),測量以毫秒的形式從1970年1月1日的午夜開始。結果為0表示該事件未發生(例如redirectEnd或者redirectStart等)。
這些事件所代表的含義在Microsoft's performance.timing documentation 和 更加正式的 W3C Editor's Draft 中都有描述。IE9支持除了secureConnectionStart時間外在API草案中描述的所有屬性,並且IE9額外提供了msFirstPaint事件,該事件在dcoument display開始,在loadEventEnd之后觸發。
這里有一張從 Navigation Timing draft 弄來的 performance.timing 事件的順序圖:
當load/unload動作被觸發時,也可能是提示關閉當前文檔時(即回車鍵在url地址欄中按下,頁面被再次刷新,submit按鈕被點擊)。如果當前窗口中沒有前一個文檔,那么navigationStart的值就是fetchStart。
它可能是頁面重定向時的開始時間(如果存在重定向的話)或者是0。
unloadEventStart:
如果被請求的文檔來自於前一個同源(同源策略)的文檔,那么該屬性存儲的是瀏覽器開始卸載前一個文檔的時刻。否則的話(前一個文檔非同源或者沒有前一個文檔),為0。
unloadEventEnd:
表示同源的前一個文檔卸載完成的時刻。如果前一個文檔不存在或者非同源,則為0。
如果存在重定向的話,redirectEnd表示最后一次重定向后服務器端response的數據被接收完畢的時間。否則的話就是0。
fetchStart是指在瀏覽器發起任何請求之前的時間值。在fetchStart和domainLookupStart之間,瀏覽器會檢查當前文檔的緩存。
這個屬性是指當瀏覽器開始檢查當前域名的DNS之前的那一時刻。如果因為任何原因沒有去檢查DNS(即瀏覽器使用了緩存,持久連接,或者本地資源),那么它的值等同於fetchStart。
指瀏覽器完成DNS檢查時的時間。如果DNS沒有被檢查,那么它的值等同於fetchStart。
當瀏覽器開始於服務器連接時的時間。如果資源取自緩存(或者服務器由於其他任何原因沒有建立連接,例如持久連接),那么它的值等同於domainLookupEnd。
當瀏覽器端完成與服務器端建立連接的時刻。如果沒有建立連接它的值等同於domainLookupEnd。
可選。如果頁面使用HTTPS,它的值是安全連接握手之前的時刻。如果該屬性不可用,則返回undefined。如果該屬性可用,但沒有使用HTTPS,則返回0。
指客戶端收到從服務器端(或緩存、本地資源)響應回的第一個字節的數據的時刻。
指客戶端收到從服務器端(或緩存、本地資源)響應回的最后一個字節的數據的時刻。
指document對象創建完成的時刻。
指文檔解析完成的時刻,包括在“傳統模式”下被阻塞的通過script標簽加載的內容(除了使用defer或者async屬性異步加載的情況)。
當DOMContentLoaded事件觸發之前,瀏覽器完成所有script(包括設置了defer屬性但未設置async屬性的script)的下載和解析之后的時刻。
當DOMContentLoaded事件完成之后的時刻。它也是javascript類庫中DOMready事件觸發的時刻。
如果已經沒有任何延遲加載的事件(所有圖片的加載)阻止load事件發生,那么該時刻將會將document.readyState屬性設置為"complete",此時刻就是domComplete。
該屬性返回的是load事件剛剛發生的時刻,如果load事件還沒有發生,則返回0。
該屬性返回load事件完成之后的時刻。如果load事件未發生,則返回0。
檢測用戶通過哪種方式來到此頁面:
我們有幾種方式來打開一個頁面,例如,在地址欄輸入url,刷新當前頁面,通過history的前進后退。這時候 performance.navigation 就派上用場了。這個 API 有兩個屬性:
-
redirectCount:頁面請求被重定向的次數
-
type:頁面被載入的方式。
以下列舉了 type 屬性的三種取值情況:
-
0:用戶通過點擊鏈接或者在瀏覽器地址欄輸入URL的方式進入頁面。
-
1:頁面重載。
-
2:通過瀏覽器history的前進或后退進入頁面。
eg: 你通過的方式進入頁面。
實時頁面性能測試:
通過 Navigation Timing API ,我們可以精確實時的獲取真實用戶的在實際網絡環境中的頁面加載速度,而不是僅僅在開發環境、公司網絡中測試頁面加載速度。
頁面性能統計:
我們甚至可以使用 XHR 將用戶每次瀏覽網頁時的 performance.timing 數據發送到服務器端。這種方式是實時的,不過效率比較低。或者,可以使用本地存儲的方式將用戶頁面性能的數據存儲在本地並周期性的打包發送到服務器端進行分析。通過這種方式,navigation timing API 實現了一種簡單的提供頁面性能歷史數據的方法。
附錄:
1. 2012.03.01: Kasia 寫了一個非常不錯數據可視化的書簽。
2. 另外一個Chrome插件。
源文檔來自:http://www.html5rocks.com/en/tutorials/webperformance/basics/ 。
參考:
本作品采用知識共享署名-非商業性使用 3.0 中國大陸許可協議進行許可。