前段時間在讀Vue源碼的時候,發現了這樣一個API——Window.Performance。當時徹底不知道這是什麼?在查閱了一些資料後,大體明白了這個API的做用。下面一塊兒來看看什麼是Performance。
其實光看這個API的名字,咱們就能大體猜到這必定是和性能相關的。來看看MDN上關於它的介紹。html
The Performance interface provides access to performance-related information for the current page. It's part of the High Resolution Time API, but is enhanced by the Performance Timeline API, the Navigation Timing API, the User Timing API, and the Resource Timing API.
Performace接口容許訪問當前頁面性能相關的信息。它是High Resolution Time API的一部分。可是它被Performance Timeline API, the Navigation Timing API, the User Timing API, and the Resource Timing API擴展加強了。實際上Performance的主要功能都是由這幾個API提供的。
單單看上面的內容,你們必定仍是會感到疑惑,這performace到底是個什麼東西?ok,咱們直接打開百度的網頁,而後在控制檯裏輸出Window.performance(window.performace返回的就是performance對象)html5
Performance對象裏出現了4個屬性。咱們分別來看看這4個屬性都表明了什麼意思?web
timing對象提供了各類與瀏覽器處理相關的時間數據。具體以下表chrome
名稱 | 做用(這裏全部時間戳都表明UNIX毫秒時間戳) |
---|---|
connectEnd | 瀏覽器與服務器之間的鏈接創建時的時間戳,鏈接創建指的是全部握手和認證過程所有結束 |
connectStart | HTTP請求開始向服務器發送時的時間戳,若是是持久鏈接,則等同於fetchStart。 |
domComplete | 當前網頁DOM結構生成時,也就是Document.readyState屬性變爲「complete」,而且相應的readystatechange事件觸發時的時間戳。 |
domContentLoadedEventEnd | 當前網頁DOMContentLoaded事件發生時,也就是DOM結構解析完畢、全部腳本運行完成時的時間戳。 |
domContentLoadedEventStart | 當前網頁DOMContentLoaded事件發生時,也就是DOM結構解析完畢、全部腳本開始運行時的時間戳。 |
domInteractive | 當前網頁DOM結構結束解析、開始加載內嵌資源時,也就是Document.readyState屬性變爲「interactive」、而且相應的readystatechange事件觸發時的時間戳。 |
domLoading | 當前網頁DOM結構開始解析時,也就是Document.readyState屬性變爲「loading」、而且相應的readystatechange事件觸發時的時間戳。 |
domainLookupEnd | 域名查詢結束時的時間戳。若是使用持久鏈接,或者從本地緩存獲取信息的,等同於fetchStart |
domainLookupStart | 域名查詢開始時的時間戳。若是使用持久鏈接,或者從本地緩存獲取信息的,等同於fetchStart |
fetchStart | 瀏覽器準備經過HTTP請求去獲取頁面的時間戳。在檢查應用緩存以前發生。 |
loadEventEnd | 當前網頁load事件的回調函數結束時的時間戳。若是該事件尚未發生,返回0。 |
loadEventStart | 當前網頁load事件的回調函數開始時的時間戳。若是該事件尚未發生,返回0。 |
navigationStart | 當前瀏覽器窗口的前一個網頁關閉,發生unload事件時的時間戳。若是沒有前一個網頁,就等於fetchStart |
redirectEnd | 最後一次重定向完成,也就是Http響應的最後一個字節返回時的時間戳。若是沒有重定向,或者上次重定向不是同源的。則爲0 |
redirectStart | 第一次重定向開始時的時間戳,若是沒有重定向,或者上次重定向不是同源的。則爲0 |
requestStart | 瀏覽器向服務器發出HTTP請求時(或開始讀取本地緩存時)的時間戳。 |
responseEnd | 瀏覽器從服務器收到(或從本地緩存讀取)最後一個字節時(若是在此以前HTTP鏈接已經關閉,則返回關閉時)的時間戳 |
responseStart | 瀏覽器從服務器收到(或從本地緩存讀取)第一個字節時的時間戳。 |
secureConnectionStart | 瀏覽器與服務器開始安全連接的握手時的時間戳。若是當前網頁不要求安全鏈接,則返回0。 |
unloadEventEnd | 若是前一個網頁與當前網頁屬於同一個域下,則表示前一個網頁的unload回調結束時的時間戳。若是沒有前一個網頁,或者以前的網頁跳轉不是屬於同一個域內,則返回值爲0。 |
unloadEventStart | 若是前一個網頁與當前網頁屬於同一個域下,則表示前一個網頁的unload事件發生時的時間戳。若是沒有前一個網頁,或者以前的網頁跳轉不是屬於同一個域內,則返回值爲0。 |
瞭解上面timeing提供的各類屬性以後,咱們能夠計算出網頁在加載時候某一部分消耗的具體時間,能夠精確到千分之一毫秒。例如要計算出發送請求到接受完數據所消耗的時間。瀏覽器
const timing = window.performance.timing const contactDuration = timing.responseEnd - timing.requestStart
PerformanceNavigation接口呈現瞭如何導航到當前文檔的信息。PerformanceNavigation有兩個屬性,一個是type,表示如何導航到當前頁面的,主要有4個值。緩存
另一個屬性是redirectCount,表示到達當前頁面以前通過幾回重定向。安全
表示performance性能測試開始的時間。是一個高精度時間戳(千分之一毫秒)服務器
表示當瀏覽器資源時間性能緩衝區已滿時會觸發的回調函數。下面是mdn上關於這個屬性的一個demo。這個demo的主要內容是當緩衝區內容滿時,調用buffer_full函數。框架
function buffer_full(event) { console.log("WARNING: Resource Timing Buffer is FULL!"); performance.setResourceTimingBufferSize(200); } function init() { // Set a callback if the resource buffer becomes filled performance.onresourcetimingbufferfull = buffer_full; } <body onload="init()">
一個非標準屬性,由chrome瀏覽器提供。這個屬性提供了一個能夠獲取到基本內存使用狀況的對象。dom
先來看看MDN中關於mark方法的定義
The mark() method creates a timestamp in the browser's performance entry buffer with the given name.
這段話能夠分解出三個關鍵詞。首先timestamp,這裏的timestamp指的是高精度時間戳(千分之一毫秒),其次是performance entry buffer。performance entry buffer指的是存儲performance實例對象的區域,初始值爲空。最後就是given name,表示生成的每個timestamp都有相應的名稱。
因此這句話就能夠理解成,在瀏覽器的performance entry buffer中,根據名稱生成高精度時間戳。也就是不少人說過的「打點」。
一樣先來看看MDN上關於measure的定義
The measure() method creates a named timestamp in the browser's performance entry buffer between two specified marks (known as the start mark and end mark, respectively). The named timestamp is referred to as a measure.
這段定義和上面mark的定義有些相似,其最核心的不一樣點在於這句話。between two specified marks。因此measure是指定兩個mark點之間的時間戳。若是說mark能夠理解爲"打點"的話,measure就能夠理解爲"連線"。
咱們來看一個使用mark和measure的小demo,這個例子也是引用MDN,這裏作一下簡單講解。
// 標記一個開始點 performance.mark("mySetTimeout-start"); // 等待1000ms setTimeout(function() { // 標記一個結束點 performance.mark("mySetTimeout-end"); // 標記開始點和結束點之間的時間戳 performance.measure( "mySetTimeout", "mySetTimeout-start", "mySetTimeout-end" ); // 獲取全部名稱爲mySetTimeout的measures var measures = performance.getEntriesByName("mySetTimeout"); var measure = measures[0]; console.log("setTimeout milliseconds:", measure.duration) // 清除標記 performance.clearMarks(); performance.clearMeasures(); }, 1000);
結果如圖
能夠看到,高精度的時間戳是很是精準的。(咱們知道因爲執行隊列的緣由,setTimeout不會在給定的1000ms以後就當即執行)
Performance API提供了不少方便測試咱們程序性能的接口。好比mark和measure。不少優秀的框架也用到了這個API進行測試,好比我最近在看的Vue框架。它裏面就頻繁用到了mark和measure來測試程序性能。因此想要開發高性能的web程序,瞭解Performace API仍是很是重要的。
【1】MDN Performance, Performance
【2】User Timing API
【3】performace entry buffer