使用performance進行網頁性能監控
由於項目需要, 需要對網頁的一些性能進行監控, 接觸到了performance,
window.performance 提供了一組精確的數據,經過簡單的計算就能得出一些網頁性能數據, 將這些數據存儲為日誌, 可有效的對網頁性能進行監控.
首先看一下在Chrome 的控制臺執行window.performance會出現什麽
下面是對這些屬性的詳細解釋:
1 performance = { 2 // memory 是非標準屬性,只在 Chrome 有 3 //這個屬性提供了一個可以獲取到基本內存使用情況的對象 4 memory: { 5 usedJSHeapSize: 10000000, //JS 對象(包括V8引擎內部對象)占用的內存 6 totalJSHeapSize: 10000000, // 可使用的內存 7 jsHeapSizeLimit: 2190000000 // 內存大小限制 8 }, 9 10 // navigation: 提供操作(包含在 timing 裏時間)的有用上下文 11 //包括頁面是加載還是刷新、發生了多少次重定向,等等。 12 navigation: { 13 redirectCount: 0, // 重定向次數 14 type: 0 // 0 正常進入的頁面(即非刷新、非重定向等)15 // 1 通過 window.location.reload() (即刷新頁面) 16 // 2 通過瀏覽器的前進後退按鈕進入的頁面(歷史記錄) 17 // 255 非以上方式進入的頁面 18 }, 19 20 timing: { 21 // 同一個瀏覽器上下文的上一個文檔卸載(unload)結束時的UNIX時間戳。 22 //如果沒有上一個文檔,這個值會和fetchStart相同。 23 navigationStart: 1441112691935,24 25 // 上一個文檔unload事件拋出時的UNIX時間戳。 26 //如果沒有上一個文檔,這個值會返回0. 27 unloadEventStart: 0, 28 29 // 和 unloadEventStart 相對應,unload事件處理完成時的UNIX時間戳。 30 //如果沒有上一個文檔,這個值會返回0. 31 unloadEventEnd: 0, 32 33 // 第一個HTTP重定向開始時的UNIX時間戳。 34 //如果沒有重定向,或者重定向中的一個不同源,這個值會返回0. 35 redirectStart: 0, 36 37 // 最後一個HTTP重定向完成時(也就是說是HTTP響應的最後一個比特直接被收到的時間)的UNIX時間戳。 38 //如果沒有重定向,或者重定向中的一個不同源,這個值會返回0. 39 redirectEnd: 0, 40 41 // 瀏覽器準備好使用HTTP請求來獲取(fetch)文檔的UNIX時間戳。這個時間點會在檢查任何應用緩存之前。 42 fetchStart: 1441112692155, 43 44 // DNS 域名查詢開始的UNIX時間戳。 45 //如果使用了持續連接(persistent connection),或者這個信息存儲到了緩存或者本地資源上,這個值將和fetchStart一致。 46 domainLookupStart: 1441112692155, 47 48 // DNS 域名查詢完成的時間. 49 //如果使用了本地緩存(即無 DNS 查詢)或持久連接,則與 fetchStart 值相等 50 domainLookupEnd: 1441112692155, 51 52 // HTTP(TCP) 域名查詢結束的UNIX時間戳。 53 //如果使用了持續連接(persistent connection),或者這個信息存儲到了緩存或者本地資源上,這個值將和 fetchStart一致。 54 connectStart: 1441112692155, 55 56 // HTTP(TCP) 返回瀏覽器與服務器之間的連接建立時的Unix毫秒時間戳。 57 // 如果建立的是持久連接,則返回值等同於fetchStart屬性的值。 58 //連接建立指的是所有握手和認證過程全部結束。 59 connectEnd: 1441112692155, 60 61 // HTTPS 返回瀏覽器與服務器開始安全鏈接的握手時的Unix毫秒時間戳。 62 //如果當前網頁不要求安全連接,則返回0。 63 secureConnectionStart: 0, 64 65 // 返回瀏覽器向服務器發出HTTP請求時(或開始讀取本地緩存時)的Unix毫秒時間戳。 66 requestStart: 1441112692158, 67 68 // 返回瀏覽器從服務器收到(或從本地緩存讀取)第一個字節時的Unix毫秒時間戳。 69 //如果傳輸層在開始請求之後失敗並且連接被重開,該屬性將會被數制成新的請求的相對應的發起時間。 70 responseStart: 1441112692686, 71 72 // 返回瀏覽器從服務器收到(或從本地緩存讀取,或從本地資源讀取)最後一個字節時(如果在此之前HTTP連接已經關閉,則返回關閉時)的Unix毫秒時間戳。 73 responseEnd: 1441112692687, 74 75 // 當前網頁DOM結構開始解析時(即Document.readyState屬性變為“loading”、相應的 readystatechange事件觸發時)的Unix毫秒時間戳。 76 domLoading: 1441112692690, 77 78 // 當前網頁DOM結構結束解析、開始加載內嵌資源時(即Document.readyState屬性變為“interactive”、相應的readystatechange事件觸發時)的Unix毫秒時間戳。 79 domInteractive: 1441112693093, 80 81 // 當解析器發送DOMContentLoaded 事件,即所有需要被執行的腳本已經被解析時的Unix毫秒時間戳。 82 domContentLoadedEventStart: 1441112693093, 83 84 // 當所有需要立即執行的腳本已經被執行(不論執行順序)時的Unix毫秒時間戳。 85 domContentLoadedEventEnd: 1441112693101, 86 87 // 當前文檔解析完成,即Document.readyState 變為 ‘complete‘且相對應的readystatechange 被觸發時的Unix毫秒時間戳 88 domComplete: 1441112693214, 89 90 // load事件被發送時的Unix毫秒時間戳。如果這個事件還未被發送,它的值將會是0。 91 92 loadEventStart: 1441112693214, 93 94 // 當load事件結束,即加載事件完成時的Unix毫秒時間戳。如果這個事件還未被發送,或者尚未完成,它的值將會是0. 95 loadEventEnd: 1441112693215 96 } 97 };
通過這些屬性, 能夠計算出一些重要的網頁性能數據:
// 計算加載時間 function getPerformanceTiming () { var performance = window.performance; if (!performance) { // 當前瀏覽器不支持 return; } var t = performance.timing; var times = {}; //頁面加載完成的時間 times.loadPage = t.loadEventEnd - t.navigationStart; //【重要】解析 DOM 樹結構的時間 times.domReady = t.domComplete - t.responseEnd; //【重要】重定向的時間 times.redirect = t.redirectEnd - t.redirectStart; //【重要】DNS 查詢時間 times.lookupDomain = t.domainLookupEnd - t.domainLookupStart; //【重要】讀取頁面第一個字節的時間 // TTFB 即 Time To First Byte times.ttfb = t.responseStart - t.navigationStart; //【重要】內容加載完成的時間 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還提供了一些方法供使用
Performance.now()
返回一個 時間戳,表示從參考時刻開始經過的毫秒量
該時間戳的值是從 window.performance.timing 接口的navigationStart屬性中的時間戳值為起始點開始計時的.
和JavaScript中其他可用的時間類函數(比如Date.now)不同的是,window.performance.now()返回的時間戳沒有被限制在一毫秒的精確度內,而它使用了一個浮點數來達到微秒級別的精確度.
另外一個不同點是,window.performance.now()是以一個恒定的速率慢慢增加的,它不會受到系統時間的影響(可能被其他軟件調整)
使用示例:
let t0 = window.performance.now(); doSomething(); let t1 = window.performance.now(); console.log("doSomething函數執行了" + (t1 - t0) + "毫秒.")
Performance.mark()
在瀏覽器的性能輸入緩沖區中創建一個 timestamp,基於給定的 name
示例:
function create_mark(name) { if (performance.mark === undefined) { console.log("performance.mark Not supported"); return; } // Create the performance mark performance.mark(name); // mark 方法是可以創建多條同名 performanceEntry 的,例如: // performance.mark("begin") // performance.mark("begin") // performance.mark("begin") // performance.mark("begin") // performance.getEntriesByName("begin") // [...] // 0: PerformanceMark { name: "begin", entryType: "mark", startTime: 94661370.14, … } // ?1: PerformanceMark { name: "begin", entryType: "mark", startTime: 95542853.4, … }? // 2: PerformanceMark { name: "begin", entryType: "mark", startTime: 95545560.92, … }? // 3: PerformanceMark { name: "begin", entryType: "mark", startTime: 95548089.94, … }? // length: 4? // __proto__: Array [] }
Performance.clearMarks()
移除給定的 mark,從瀏覽器的性能輸入緩沖區中
下面的例子演示clearMarks() 的兩種用法。
function clear_mark(name) { if (performance.clearMarks === undefined) { console.log("performance.clearMarks Not supported"); return; } //移除所有標記了此名稱的peformance entry performance.clearMarks(name); } function clear_all_marks() { if (performance.clearMarks === undefined) { console.log("performance.clearMarks Not supported"); return; } //從performance 緩沖區中移除所有標記的performance entry performance.clearMarks(); }
Performance.clearMeasures()
移除給定的 measure,從瀏覽器的性能輸入緩沖區中
Performance.clearResourceTimings()
移除所有的 entryType 是 "resource" 的 performance entries,從瀏覽器的性能數據緩沖區中
Performance.getEntries()
返回一個 PerformanceEntry 對象的列表,基於給定的 filter
Performance.getEntriesByName()
返回一個 PerformanceEntry 對象的列表,基於給定的 name 和 entry type
Performance.getEntriesByType()
返回一個 PerformanceEntry 對象的列表,基於給定的 entry type
Performance.measure()
在瀏覽器的指定 start mark 和 end mark 間的性能輸入緩沖區中創建一個指定的 timestamp
Performance.setResourceTimingBufferSize()
將瀏覽器的資源 timing 緩沖區的大小設置為 "resource" type performance entry 對象的指定數量
Performance.toJSON()
是一個 JSON 格式轉化器,返回 Performance 對象的 JSON 對象
使用performance的這些屬性和方法, 能夠準確的記錄下我們想要的時間, 再加上日誌采集等功能的輔助,我們就能很容易的掌握自己網站的各項性能指標了.
使用performance進行網頁性能監控