天天看點

Performance — 前端性能監控利器 方法詳解

Performance — 前端性能監控利器 方法詳解

轉載 https://www.cnblogs.com/bldxh/p/6857324.html
使用示例 點選此處

最近在寫一個監控腳本,終于有機會接觸到了這一塊,整理後寫下了本文。

Performance是一個做前端性能監控離不開的API,最好在頁面完全加載完成之後再使用,因為很多值必須在頁面完全加載之後才能得到。最簡單的辦法是在window.onload事件中讀取各種資料。

屬性

timing (PerformanceTiming)

從輸入url到使用者可以使用頁面的全過程時間統計,會傳回一個PerformanceTiming對象,機關均為毫秒

按觸發順序排列所有屬性:(更詳細标準的解釋請參看:W3C Editor’s Draft)

navigationStart:在同一個浏覽器上下文中,前一個網頁(與目前頁面不一定同域)unload 的時間戳,如果無前一個網頁 unload ,則與 fetchStart 值相等

unloadEventStart:前一個網頁(與目前頁面同域)unload 的時間戳,如果無前一個網頁 unload 或者前一個網頁與目前頁面不同域,則值為 0

unloadEventEnd:和 unloadEventStart 相對應,傳回前一個網頁 unload 事件綁定的回調函數執行完畢的時間戳

redirectStart:第一個 HTTP 重定向發生時的時間。有跳轉且是同域名内的重定向才算,否則值為 0

redirectEnd:最後一個 HTTP 重定向完成時的時間。有跳轉且是同域名内的重定向才算,否則值為 0

fetchStart:浏覽器準備好使用 HTTP 請求抓取文檔的時間,這發生在檢查本地緩存之前

domainLookupStart:DNS 域名查詢開始的時間,如果使用了本地緩存(即無 DNS 查詢)或持久連接配接,則與 fetchStart 值相等

domainLookupEnd:DNS 域名查詢完成的時間,如果使用了本地緩存(即無 DNS 查詢)或持久連接配接,則與 fetchStart 值相等

connectStart:HTTP(TCP) 開始建立連接配接的時間,如果是持久連接配接,則與 fetchStart 值相等,如果在傳輸層發生了錯誤且重建立立連接配接,則這裡顯示的是建立立的連接配接開始的時間

connectEnd:HTTP(TCP) 完成建立連接配接的時間(完成握手),如果是持久連接配接,則與 fetchStart 值相等,如果在傳輸層發生了錯誤且重建立立連接配接,則這裡顯示的是建立立的連接配接完成的時間

注意:這裡握手結束,包括安全連接配接建立完成、SOCKS 授權通過

secureConnectionStart:HTTPS 連接配接開始的時間,如果不是安全連接配接,則值為 0

requestStart:HTTP 請求讀取真實文檔開始的時間(完成建立連接配接),包括從本地讀取緩存,連接配接錯誤重連時,這裡顯示的也是建立立連接配接的時間

responseStart:HTTP 開始接收響應的時間(擷取到第一個位元組),包括從本地讀取緩存

responseEnd:HTTP 響應全部接收完成的時間(擷取到最後一個位元組),包括從本地讀取緩存

domLoading:開始解析渲染 DOM 樹的時間,此時 Document.readyState 變為 loading,并将抛出 readystatechange 相關事件

domInteractive:完成解析 DOM 樹的時間,Document.readyState 變為 interactive,并将抛出 readystatechange 相關事件

注意:隻是 DOM 樹解析完成,這時候并沒有開始加載網頁内的資源

domContentLoadedEventStart:DOM 解析完成後,網頁内資源加載開始的時間,文檔發生 DOMContentLoaded事件的時間

domContentLoadedEventEnd:DOM 解析完成後,網頁内資源加載完成的時間(如 JS 腳本加載執行完畢),文檔的DOMContentLoaded 事件的結束時間

domComplete:DOM 樹解析完成,且資源也準備就緒的時間,Document.readyState 變為 complete,并将抛出 readystatechange 相關事件

loadEventStart:load 事件發送給文檔,也即 load 回調函數開始執行的時間,如果沒有綁定 load 事件,值為 0

loadEventEnd:load 事件的回調函數執行完畢的時間,如果沒有綁定 load 事件,值為 0

常用計算:

DNS查詢耗時 :domainLookupEnd - domainLookupStart

TCP連結耗時 :connectEnd - connectStart

request請求耗時 :responseEnd - responseStart

解析dom樹耗時 : domComplete - domInteractive

白屏時間 :responseStart - navigationStart

domready時間(使用者可操作時間節點) :domContentLoadedEventEnd - navigationStart

onload時間(總下載下傳時間) :loadEventEnd - navigationStart

navigation

旨在告訴開發者目前頁面是通過什麼方式導航過來的,隻有兩個屬性:type,redirectCount

type:标志頁面導航類型,值如下表

type常數 枚舉值 描述

TYPE_NAVIGATE 0 普通進入,包括:點選連結、在位址欄中輸入 URL、表單送出、或者通過除下表中 TYPE_RELOAD 和 TYPE_BACK_FORWARD 的方式初始化腳本。

TYPE_RELOAD 1 通過重新整理進入,包括:浏覽器的重新整理按鈕、快捷鍵重新整理、location.reload()等方法。

TYPE_BACK_FORWARD 2 通過操作曆史記錄進入,包括:浏覽器的前進後退按鈕、快捷鍵操作、history.forward()、history.back()、history.go(num)。

TYPE_UNDEFINED 255 其他非以上類型的方式進入。

**注意:**稍帶個小知識,history.go(url)這種非标準寫法目前主流浏覽器均不支援,問題可參考http://stackoverflow.com/questions/6277283/history-gourl-issue

redirectCount:表示到達最終頁面前,重定向的次數,但是這個接口有同源政策限制,即僅能檢測同源的重定向。

注意:所有前端模拟的重定向都無法統計到,因為不屬于HTTP重定向

memory

描述記憶體多少,是在Chrome中添加的一個非标準屬性。

jsHeapSizeLimit: 記憶體大小限制

totalJSHeapSize: 可使用的記憶體

usedJSHeapSize: JS對象(包括V8引擎内部對象)占用的記憶體,不能大于totalJSHeapSize,如果大于,有可能出現了記憶體洩漏

方法

getEntries()

擷取所有資源請求的時間資料,這個函數傳回一個按startTime排序的對象數組,數組成員除了會自動根據所請求資源的變化而改變以外,還可以用mark(),measure()方法自定義添加,該對象的屬性中除了包含資源加載時間還有以下五個屬性。

name:資源名稱,是資源的絕對路徑或調用mark方法自定義的名稱

startTime:開始時間

duration:加載時間

entryType:資源類型,entryType類型不同數組中的對象結構也不同!具體見下

initiatorType:誰發起的請求,具體見下

entryType的值:

值 該類型對象 描述

mark PerformanceMark 通過mark()方法添加到數組中的對象

measure PerformanceMeasure 通過measure()方法添加到數組中的對象

paint PerformancePaintTiming 值為first-paint’首次繪制、'first-contentful-paint’首次内容繪制。

resource PerformanceResourceTiming 所有資源加載時間,用處最多

navigation PerformanceNavigationTiming 現除chrome和Opera外均不支援,導航相關資訊

frame PerformanceFrameTiming 現浏覽器均未支援

也可參見:https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/entryType

initiatorType的值:

發起對象 值 描述

a Element link/script/img/iframe等 通過标簽形式加載的資源,值是該節點名的小寫形式

a CSS resourc css 通過css樣式加載的資源,比如background的url方式加載資源

a XMLHttpRequest object xmlhttprequest/fetch 通過xhr加載的資源

a PerformanceNavigationTiming object navigation 當對象是PerformanceNavigationTiming時傳回

//根據entryType類型傳回的不同對象

PerformanceMark:{ //通過mark()方法添加的對象

entryType:“mark”

name:調用mark()方法時自定義的名字

startTime: 做标記的時間

duration:0

}

PerformanceMeasure:{ //通過measure()方法添加的對象

entryType:“measure”

name:調用measure()方法時自定義的名字

startTime: 開始量的時間

duration:标記的兩個量的時間間隔

}

PerformancePaintTiming:{ // Chrome 60 新增類型

entryType:“paint”

name:first-paint" 或 “first-contentful-paint”

startTime: 繪制的時間戳

duration: 0

}

PerformanceResourceTiming:{ //可以用來做一個精準的進度條

entryType:“resource”

name:資源的絕對路徑,即URL

startTime: 即将抓取資源的時間,

duration: responseEnd - startTime

initiatorType:略!/:傲嬌臉

//其他屬性請參考performance.timing

}

PerformanceNavigationTiming:{

entryType:“navigation”

name:本頁路由,即位址欄看到的位址

startTime: 0

duration: loadEventEnd - startTime

initiatorType:“navigation”

//其他屬性請參考performance.timing

}

請注意:

目前通過,加載資源,initiatorType還無法傳回"audio"和"video",chrome中隻能傳回空字元串,firfox傳回"other"

如果一個圖檔在頁面内既用img引入,又作為背景圖檔引入,那麼initiatorType傳回的"img"

performance.getEntries(params)這種形式仍出于草案階段,目前仍有很多浏覽器未支援。但是非常有用,期待早些實作。

使用該方法統計資源資訊的時候首先可以合理利用clearResourceTimings清除已統計過的對象避免重複統計,其次要過濾掉因上報統計資料而産生的對象。

getEntriesByName(name,type[optional]),getEntriesByType(type)

name:想要篩選出的資源名

type:entryType的值中一個

傳回值仍是一個數組,這個數組相當于getEntries()方法經過所填參數篩選後的一個子集

clearResourceTimings();

該方法無參數無傳回值,可以清楚目前所有entryType為"resource"的資料,用于寫單頁應用的統計腳本非常有用

mark(name),measure(name, startMark, endMark),clearMarks(),clearMeasures()

用于做标記和清除标記,供使用者自定義統計一些資料,比如某函數運作耗時等

name:自定義的名稱,不要和getEntries()傳回的數組中其他name重複

startMark:作為開始時間的标記名稱或PerformanceTiming的一個屬性

endMark:作為結束時間的标記名稱或PerformanceTiming的一個屬性

建立标記:mark(name);

記錄兩個标記的時間間隔:measure(name, startMark, endMark);

清除指定标記:window.performance.clearMarks(name);

清除所有标記:window.performance.clearMarks();

清除指定記錄間隔資料:window.performance.clearMeasures(name);

清除所有記錄間隔資料:window.performance.clearMeasures();

now()

performance.now()是目前時間與performance.timing.navigationStart的時間差,以微秒(百萬分之一秒)為機關的時間,與 Date.now()-performance.timing.navigationStart的差別是不受系統程式執行阻塞的影響,是以更加精準。

友情提示

目前主流浏覽器雖然都已支援Performance對象,但是并不能支援它上面的全部屬性和方法,本文主要依據chrome編寫,是以提到的chrome浏覽器都是相容的,其他具體使用時相容性請自行測試,目前已測如下:

1.safari浏覽器(包括mac和ios)隻支援navigation,timing,now其餘均不支援

2.微信浏覽器支援timing,navigation屬性,不支援performance.getEntries方法