// 獲取 performance 數據 var performance = { // memory 是非標準屬性,只在 Chrome 有 // 財富問題:我有多少內存 memory: { usedJSHeapSize: 16100000, // JS 對象(包括V8引擎內部對象)佔用的內存,必定小於 totalJSHeapSize totalJSHeapSize: 35100000, // 可以使用的內存 jsHeapSizeLimit: 793000000 // 內存大小限制 }, // 哲學問題:我從哪裏來? navigation: { redirectCount: 0, // 若是有重定向的話,頁面經過幾回重定向跳轉而來 type: 0 // 0 即 TYPE_NAVIGATENEXT 正常進入的頁面(非刷新、非重定向等) // 1 即 TYPE_RELOAD 經過 window.location.reload() 刷新的頁面 // 2 即 TYPE_BACK_FORWARD 經過瀏覽器的前進後退按鈕進入的頁面(歷史記錄) // 255 即 TYPE_UNDEFINED 非以上方式進入的頁面 }, timing: { // 在同一個瀏覽器上下文中,前一個網頁(與當前頁面不必定同域)unload 的時間戳,若是無前一個網頁 unload ,則與 fetchStart 值相等 navigationStart: 1441112691935, // 前一個網頁(與當前頁面同域)unload 的時間戳,若是無前一個網頁 unload 或者前一個網頁與當前頁面不一樣域,則值爲 0 unloadEventStart: 0, // 和 unloadEventStart 相對應,返回前一個網頁 unload 事件綁定的回調函數執行完畢的時間戳 unloadEventEnd: 0, // 第一個 HTTP 重定向發生時的時間。有跳轉且是同域名內的重定向纔算,不然值爲 0 redirectStart: 0, // 最後一個 HTTP 重定向完成時的時間。有跳轉且是同域名內部的重定向纔算,不然值爲 0 redirectEnd: 0, // 瀏覽器準備好使用 HTTP 請求抓取文檔的時間,這發生在檢查本地緩存以前 fetchStart: 1441112692155, // DNS 域名查詢開始的時間,若是使用了本地緩存(即無 DNS 查詢)或持久鏈接,則與 fetchStart 值相等 domainLookupStart: 1441112692155, // DNS 域名查詢完成的時間,若是使用了本地緩存(即無 DNS 查詢)或持久鏈接,則與 fetchStart 值相等 domainLookupEnd: 1441112692155, // HTTP(TCP) 開始創建鏈接的時間,若是是持久鏈接,則與 fetchStart 值相等 // 注意若是在傳輸層發生了錯誤且從新創建鏈接,則這裏顯示的是新創建的鏈接開始的時間 connectStart: 1441112692155, // HTTP(TCP) 完成創建鏈接的時間(完成握手),若是是持久鏈接,則與 fetchStart 值相等 // 注意若是在傳輸層發生了錯誤且從新創建鏈接,則這裏顯示的是新創建的鏈接完成的時間 // 注意這裏握手結束,包括安全鏈接創建完成、SOCKS 受權經過 connectEnd: 1441112692155, // HTTPS 鏈接開始的時間,若是不是安全鏈接,則值爲 0 secureConnectionStart: 0, // HTTP 請求讀取真實文檔開始的時間(完成創建鏈接),包括從本地讀取緩存 // 鏈接錯誤重連時,這裏顯示的也是新創建鏈接的時間 requestStart: 1441112692158, // HTTP 開始接收響應的時間(獲取到第一個字節),包括從本地讀取緩存 responseStart: 1441112692686, // HTTP 響應所有接收完成的時間(獲取到最後一個字節),包括從本地讀取緩存 responseEnd: 1441112692687, // 開始解析渲染 DOM 樹的時間,此時 Document.readyState 變爲 loading,並將拋出 readystatechange 相關事件 domLoading: 1441112692690, // 完成解析 DOM 樹的時間,Document.readyState 變爲 interactive,並將拋出 readystatechange 相關事件 // 注意只是 DOM 樹解析完成,這時候並無開始加載網頁內的資源 domInteractive: 1441112693093, // DOM 解析完成後,網頁內資源加載開始的時間 // 在 DOMContentLoaded 事件拋出前發生 domContentLoadedEventStart: 1441112693093, // DOM 解析完成後,網頁內資源加載完成的時間(如 JS 腳本加載執行完畢) domContentLoadedEventEnd: 1441112693101, // DOM 樹解析完成,且資源也準備就緒的時間,Document.readyState 變爲 complete,並將拋出 readystatechange 相關事件 domComplete: 1441112693214, // load 事件發送給文檔,也即 load 回調函數開始執行的時間 // 注意若是沒有綁定 load 事件,值爲 0 loadEventStart: 1441112693214, // load 事件的回調函數執行完畢的時間 loadEventEnd: 1441112693215 // 字母順序 // connectEnd: 1441112692155, // connectStart: 1441112692155, // domComplete: 1441112693214, // domContentLoadedEventEnd: 1441112693101, // domContentLoadedEventStart: 1441112693093, // domInteractive: 1441112693093, // domLoading: 1441112692690, // domainLookupEnd: 1441112692155, // domainLookupStart: 1441112692155, // fetchStart: 1441112692155, // loadEventEnd: 1441112693215, // loadEventStart: 1441112693214, // navigationStart: 1441112691935, // redirectEnd: 0, // redirectStart: 0, // requestStart: 1441112692158, // responseEnd: 1441112692687, // responseStart: 1441112692686, // secureConnectionStart: 0, // unloadEventEnd: 0, // unloadEventStart: 0 }
利用performance.timing信息簡單計算出網頁性能數據css
// 計算加載時間 function getPerformanceTiming () { var performance = window.performance; if (!performance) { // 當前瀏覽器不支持 console.log('你的瀏覽器不支持 performance 接口'); return; } var t = performance.timing; var times = {}; //【重要】頁面加載完成的時間 //【緣由】這幾乎表明了用戶等待頁面可用的時間 times.loadPage = t.loadEventEnd - t.navigationStart; //【重要】解析 DOM 樹結構的時間 //【緣由】檢討下你的 DOM 樹嵌套是否是太多了! times.domReady = t.domComplete - t.responseEnd; //【重要】重定向的時間 //【緣由】拒絕重定向!好比,http://example.com/ 就不應寫成 http://example.com times.redirect = t.redirectEnd - t.redirectStart; //【重要】DNS 查詢時間 //【緣由】DNS 預加載作了麼?頁面內是否是使用了太多不一樣的域名致使域名查詢的時間太長? // 可以使用 HTML5 Prefetch 預查詢 DNS ,見:[HTML5 prefetch](http://segmentfault.com/a/1190000000633364) times.lookupDomain = t.domainLookupEnd - t.domainLookupStart; //【重要】讀取頁面第一個字節的時間 //【緣由】這能夠理解爲用戶拿到你的資源佔用的時間,加異地機房了麼,加CDN 處理了麼?加帶寬了麼?加 CPU 運算速度了麼? // TTFB 即 Time To First Byte 的意思 // 維基百科:https://en.wikipedia.org/wiki/Time_To_First_Byte times.ttfb = t.responseStart - t.navigationStart; //【重要】內容加載完成的時間 //【緣由】頁面內容通過 gzip 壓縮了麼,靜態資源 css/js 等壓縮了麼? times.request = t.responseEnd - t.requestStart; //【重要】執行 onload 回調函數的時間 //【緣由】是否太多沒必要要的操做都放到 onload 回調函數裏執行了,考慮過延遲加載、按需加載的策略麼? times.loadEvent = t.loadEventEnd - t.loadEventStart; // DNS 緩存時間 times.appcache = t.domainLookupStart - t.fetchStart; // 卸載頁面的時間 times.unloadEvent = t.unloadEventEnd - t.unloadEventStart; // TCP 創建鏈接完成握手的時間 times.connect = t.connectEnd - t.connectStart; return times; }
使用performance.now()精確程序執行時間segmentfault
performance.now()與Date.now()不一樣的是,返回了以微秒(百萬分之一秒)爲單位的時間,更加精準。瀏覽器
而且與Date.now()會受系統程序執行阻塞的影響不一樣,performance.now()的時間是以恆定速率遞增的,不受系統時間的影響(系統時間可被人爲或軟件調整)。緩存
注意Date.now()輸出的是UNIX時間,即距離1970年的時間,而performance.now()輸出的是相對於performance.timing.navigationStrart(頁面初始化)的時間。安全
使用Date.now()的差值並不是絕對精確,由於計算時間受系統限制(可能阻塞)。但使用performance.now()的差值,並不影響咱們計算程序執行的精確時間。app
// 計算程序執行的精確時間 function getFunctionTimeWithDate (func) { var timeStart = Data.now(); // 執行開始 func(); // 執行結束 var timeEnd = Data.now(); // 返回執行時間 return (timeEnd - timeStart); } function getFunctionTimeWithPerformance (func) { var timeStart = window.performance.now(); // 執行開始 func(); // 執行結束 var timeEnd = window.performance.now(); // 返回執行時間 return (timeEnd - timeStart); }
轉載自AlloyTeam:http://www.alloyteam.com/2015/09/explore-performance/dom