主要用於測試html的頁面性能采集。介紹了傳統的性能指標和采集方式,
此外介紹了Google正在力推的以用戶為中心的性能指標,以及相應的采集方式。
性能指標
目前業界常用的指標就是:白屏
、首屏
、domready
和pageloaded
四個指標,在usual-index.html中,
我們通過performance API獲取到響應的指標值。
- 白屏
一般是認為DOM Tree構建時,解析到或的時候,我們認為是白屏結束的時間點。
我們可以在這個時候使用performace.mark進行打點標記,最后可以通過performance的
entry.startTime來獲取白屏時間,其中entry.startTime是相對於performance.timing.navigationStart的時間。
<head>
...
<script>
// 通常在head標簽尾部時,打個標記,這個通常會視為白屏時間
performance.mark("first paint time");
</script>
</head>
<body>
...
<script>
// get the first paint time
const fp = Math.ceil(performance.getEntriesByName('first paint time')[0].startTime);
</script>
</body>
- 首屏
一般是首屏中的圖片加載完畢的時候,我們認為是首屏結束的時間點。我們可以對首屏中的image做onload事件綁定,
performace.mark進行打點標記,不過打點前先進行performance.clearMarks清除操作,以獲取到多張圖片最后加載完畢的時間。
<body>
<div class="app-container">
<img src="a.png" onload="heroImageLoaded()">
<img src="b.png" onload="heroImageLoaded()">
<img src="c.png" onload="heroImageLoaded()">
</div>
<script>
// 根據首屏中的核心元素確定首屏時間
performance.clearMarks("hero img displayed");
performance.mark("hero img displayed");
function heroImageLoaded() {
performance.clearMarks("hero img displayed");
performance.mark("hero img displayed");
}
</script>
...
...
<script>
// get the first screen loaded time
const fmp = Math.ceil(performance.getEntriesByName('hero img displayed')[0].startTime);
</script>
</body>
- domready與pageloaded
這兩個指標有相應的事件監聽,即document的DOMContentLoaded和window.onload,直接在事件的回調中使用performance打點即可。
<script>
document.addEventListener('DOMContentLoaded', ()=> {
performance.mark("dom ready");
});
window.onload = ()=> {
performance.mark("page loaded");
// get the domReady time
const domReady = Math.ceil(performance.getEntriesByName('dom ready')[0].startTime);
// get the page loaded time
const pageLoad = Math.ceil(performance.getEntriesByName('page loaded')[0].startTime);
}
</script>
以用戶為中心的性能指標
這個是Google力推的指標,主要從4個視覺反饋階段來描述頁面性能。
視覺反饋 | 頁面狀態 | 性能指標 |
---|---|---|
是否發生? | 導航是否成功啟動?服務器是否有響應? | 首次繪制 (FP)/首次內容繪制 (FCP) |
是否有用? | 是否已渲染可以與用戶互動的足夠內容? | 首次有效繪制 (FMP)/主角元素計時 |
是否可用? | 用戶可以與頁面交互,還是頁面仍在忙於加載? | 可交互時間 (TTI) |
是否令人愉快? | 交互是否順暢而自然,沒有滯后和卡頓? | 耗時較長的任務(在技術上不存在耗時較長的任務) |
對應的指標如下圖所示:
此外,Google也提供了一些新的API,來獲取相應的指標值。
- 首次繪制 (FP)/首次內容繪制 (FCP)
PerformanceObserver
為我們提供的新功能是,能夠在性能事件發生時訂閱這些事件,並以異步方式響應事件。
let perfomanceMetrics = {};
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// `entry` is a PerformanceEntry instance.
// `name` will be either 'first-paint' or 'first-contentful-paint'.
const metricName = entry.name;
const time = Math.round(entry.startTime + entry.duration);
if (metricName === 'first-paint') {
perfomanceMetrics.fp = time;
}
if (metricName === 'first-contentful-paint') {
perfomanceMetrics.fcp = time;
}
}
});
// Start observing the entry types you care about.
observer.observe({entryTypes: ['paint']});
- 首次有效繪制 (FMP)/主角元素計時
目前尚無標准化的 FMP 定義,一般來說,是將 FMP 視為主角元素呈現在屏幕上的時刻。
這個的計算方法就同上面介紹的首屏指標獲取,只是首屏確定的是首頁中的圖片,而 FMP 確定的是核心元素。
- 可交互時間 (TTI)
TTI 主要是通過跟蹤耗時較長的任務來確定,設置PerformanceObserver
觀察類型為 longtask 的條目,
然后可以根據耗時較長的條目的startTime和duration,來大致確認頁面處於idle的時間,從而確定 TTI 指標。
Google希望將 TTI 指標標准化,並通過 PerformanceObserver 在瀏覽器中公開,但目前並不支持。
目前只能通過一個 polyfill,檢測目前的 TTI,適用於所有支持 Long Tasks API 的瀏覽器。
該 polyfill 公開 getFirstConsistentlyInteractive() 方法,后者返回使用 TTI 值進行解析的 promise。
用法如下所示:
- 首先是在中設置PerformanceObserver,並指定監控類型為longtask。
<head>
<script>
// collect the longtask
if (PerformanceLongTaskTiming) {
window.__tti = {e: []};
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// observe the longtask to get the time to interactive (TTI)
if (entry.entryType === 'longtask') {
window.__tti.e.concat(entry);
}
}
});
observer.observe({entryTypes: ['longtask']});
}
</script>
</head>
- 然后引入tti-polyfill.js(可通過npm包獲取),獲取到tti的值。
import ttiPolyfill from './path/to/tti-polyfill.js';
ttiPolyfill.getFirstConsistentlyInteractive().then((tti) => {
...
});
- 耗時較長的任務
這個同TTI的第一步,設置PerformanceObserver,並指定監控類型為longtask,
獲取到的entry包含提供方屬性
,有助於追查導致出現耗時較長任務的代碼。
示例demo
https://github.com/huangwenming/learning-notes/tree/master/html-relevant/performance
參考資料
http://www.alloyteam.com/2015/09/explore-performance/