主要用於測試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/