Performance Timeline
是W3C性能小組提出的一個規範,定義了讓開發者在應用整個生命週期內收集各類性能指標的接口。javascript
最新的Performance Timeline Level 2
標準,取代了初版Performance Timeline
標準,它包括瞭如下三點:html
Performance
接口的基本定義PerformanceEntry
PerformanceObserver
的支持值得注意的是,在Node.js裏一樣遵循W3C的Performance Timeline
規範,實現了 Performance Hooks 接口。Performance Hooks 的API和現代瀏覽器中實現的 Performance API 是一致的。java
在瀏覽器中,咱們可使用 window 對象取得window.performance
和 window.PerformanceObserver
,而在 Node.js 程序中須要 perf_hooks 取得性能對象,以下:node
const { PerformanceObserver, performance } = require('perf_hooks');
複製代碼
W3C性能小組鼓勵開發人員在瀏覽器兼容性容許的狀況下,儘量使用 PerformanceObserver。另外,新的性能API和指標可能只能經過PerformanceObserver 接口得到。json
使用window.performance
,咱們能夠這樣去度量某個函數的性能。api
function init() {
performance.mark("startWork");
doWork();
performance.mark("endWork");
performance.measure("work", "startWork", "endWork")
measurePerf();
}
function measurePerf() {
performance
.getEntries()
.map(entry => JSON.stringify(entry, null, 2))
.forEach(json => console.log(json));
}
複製代碼
在上述代碼中,咱們使用了performance.mark
和performance.measure
來記錄性能記錄的數據。瀏覽器
performance.measure
方法會根據 startMark 和 endMark 對應的,由 performance.mark
產生的兩條記錄,來產生一條 entryType 爲 'measure' 的新記錄,並計算運行時長。bash
而後代碼裏使用了performance.getEntries
來獲取瀏覽器緩衝區中全部的性能數據記錄。異步
固然,咱們也可使用
performance.getEntriesByName
獲取指定 entryType 的性能記錄。函數
正如上文所述,咱們要想得到某項性能記錄,須要知道指定的性能事件已經發生(或者使用定時輪訓的方式),主動調用performance.getEntries
或者performance.getEntriesByName
來得到。
爲了解決這個問題,在Performance Timeline Level 2
中,除了擴展了Performance
的基本定義之外,還增長了PerformanceObserver
接口。
顧名思義,PerformanceObserver
在瀏覽器內部對Performance
實現了觀察者模式,也是現代瀏覽器支持的幾個 Observer 之一。
它解決了如下3點問題:
在兼容Performance Timeline Level 2
的瀏覽器或者 Node.js 中,能夠這樣寫:
const userTimingObserver = new PerformanceObserver(list => {
list
.getEntries()
.map(({ name, entryType, startTime, duration }) => {
const obj = {
"Duration": duration,
"Entry Type": entryType,
"Name": name,
"Start Time": startTime,
};
return JSON.stringify(obj, null, 2);
})
.forEach(console.log);
userTimingObserver.disconnect();
});
userTimingObserver.observe({entryTypes: ["mark", "measure"]});
複製代碼
另外有必要介紹一下 performanceObserver.observe
函數,它接受兩個參數entryTypes
和buffered
。
const {
performance,
PerformanceObserver
} = require('perf_hooks');
const obs = new PerformanceObserver((list, observer) => {
// 同步執行三次. 每次`list` 僅包含一項 item.
});
obs.observe({ entryTypes: ['mark'] });
for (let n = 0; n < 3; n++)
performance.mark(`test${n}`);
複製代碼
const {
performance,
PerformanceObserver
} = require('perf_hooks');
const obs = new PerformanceObserver((list, observer) => {
// 執行一次. `list` 包含3個 items.
});
obs.observe({ entryTypes: ['mark'], buffered: true });
for (let n = 0; n < 3; n++)
performance.mark(`test${n}`);
複製代碼
在Performance Timeline Level 2
規範中,擴充了performance
的定義,並增長了PerformanceObserver
的支持。
相比PerformanceObserver
,window.performance
在瀏覽器中兼容性較好,另外Performance Hooks
在 Node.js 中仍然處於 Experimental 階段。
推薦在瀏覽器兼容的狀況下使用PerformanceObserver
,使用這種觀察者模式能夠解決主動調用的問題,並且更爲優雅。