PerformanceEventTiming
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
PerformanceEventTiming
はイベントタイミング API のインターフェイスで、ユーザー操作によって発生させる特定のイベント型の待ち時間に関する分析結果を提供します。
解説
この API により、特定のイベント型(下記参照)のイベントのタイムスタンプと処理時間が提供されるので、遅いイベントを可視化することができるようになります。例えば、ユーザー操作からそのイベントハンドラーが始まるまでの時間や、イベントハンドラーが実行するまでにかかる時間を監視することができます。
この API は、first input delay (FID) (ユーザーがこのアプリを最初に操作した時点から、ブラウザーが実際にその操作に応答することができるまでの時間)を測定するのに特に有益です。
通常、 PerformanceEventTiming
オブジェクトを扱うには、 PerformanceObserver
インスタンスを作成し、 observe()
メソッドを呼び出して、 type
オプションに "event"
または "first-input"
を渡します。 PerformanceObserver
オブジェクトのコールバックは、 PerformanceEventTiming
オブジェクトのリストとともに呼び出されます。例えば下記の例をご覧ください。
既定では、PerformanceEventTiming
項目は duration
が 104ms 以上の場合に公開されます。調査によると、 100ms 以内に処理されないユーザー入力は遅いと考えられており、 104ms は 100ms より大きい最初の 8 の倍数です(セキュリティ上の理由から、この API は最も近い 8 の倍数に丸められます)。
しかし、observe()
メソッドの durationThreshold
オプションを使用して、PerformanceObserver
を別の閾値に設定することができます。
このインターフェイスは、親である PerformanceEntry
のメソッドとプロパティを継承しています。
公開されるイベント
イベントタイミング API で公開されるイベント型は以下の通りです。
クリックイベント |
auxclick ,
click ,
contextmenu ,
dblclick
|
---|---|
変換イベント |
compositionend ,
compositionstart ,
compositionupdate
|
ドラッグ & ドロップイベント |
dragend ,
dragenter ,
dragleave ,
dragover ,
dragstart ,
drop
|
入力イベント |
beforeinput ,
input
|
キーボードイベント |
keydown ,
keypress ,
keyup
|
マウスイベント |
mousedown ,
mouseenter ,
mouseleave ,
mouseout ,
mouseover ,
mouseup
|
ポインターイベント |
pointerover ,
pointerenter ,
pointerdown ,
pointerup ,
pointercancel ,
pointerout ,
pointerleave ,
gotpointercapture ,
lostpointercapture
|
タッチイベント |
touchstart ,
touchend ,
touchcancel
|
なお、連続イベントであり、この時点では意味のあるイベントカウントやパフォーマンス指標を得ることができないため、リストに含まれていないイベントがあります。 mousemove
, pointermove
、pointerrawupdate
、touchmove
、wheel
、drag
です。
公開されるすべてのイベントのリストを取得するには、 performance.eventCounts
マップのキーを見ていくこともできます。
const exposedEventsList = [...performance.eventCounts.keys()];
コンストラクター
このインターフェイスは自分自身でコンストラクター持っていません。 PerformanceEventTiming
インターフェイスが保持している情報を取得する一般的な方法については、下記の例を参照してください。
インスタンスプロパティ
このインターフェイスは、イベントタイミングパフォーマンス項目型の以下の PerformanceEntry
プロパティを、次のように修飾子して拡張します。
PerformanceEntry.duration
読取専用-
DOMHighResTimeStamp
で、startTime
から次の描画までの時間(8ms に丸めたもの)を返します。 PerformanceEntry.entryType
読取専用-
"event"
(長いイベント)または"first-input"
(最初のユーザー操作)を返します。 PerformanceEntry.name
読取専用-
関連するイベントの型を返します。
PerformanceEntry.startTime
読取専用-
DOMHighResTimeStamp
で、関連付けられたイベントのtimestamp
プロパティを表す値を返します。これはイベントが作成された時刻であり、ユーザーの操作が発生した時刻のプロキシーと考えることができます。
このインターフェイスは以下のプロパティにも対応しています。
PerformanceEventTiming.cancelable
読取専用-
関連するイベントの
cancelable
プロパティを返します。 PerformanceEventTiming.interactionId
読取専用 Experimental-
関連するイベントを発生させたユーザー操作を一意に識別する ID を返します。
PerformanceEventTiming.processingStart
読取専用-
イベント配信が開始された時刻を表す
DOMHighResTimeStamp
を返します。ユーザー操作からイベントハンドラーが実行し始めるまでの時間を計測するには、processingStart-startTime
を計算します。 PerformanceEventTiming.processingEnd
読取専用-
イベント配信が終わった時刻を表す
DOMHighResTimeStamp
を返します。イベントハンドラーが実行するのにかかった時間を計測するには、processingEnd-processingStart
を計算します。 PerformanceEventTiming.target
読取専用-
関連付けられたイベントの最後の対象が除去されていない場合、それを返します。
インスタンスメソッド
PerformanceEventTiming.toJSON()
-
この
PerformanceEventTiming
オブジェクトの JSON 表現を返します。
例
イベントタイミング情報の取得
イベントのタイミング情報を取得するには、 PerformanceObserver
のインスタンスを作成し、 observe()
メソッドを呼び出して、 type
オプションの値として "event"
または "first-input"
を渡してください。また、ユーザーエージェントが文書の構築中にバッファリングしたイベントにアクセスするには、 buffered
を true
に設定する必要があります。 PerformanceObserver
オブジェクトのコールバックは、 PerformanceEventTiming
オブジェクトのリストとともに呼び出されます。
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
// 時間全体
const duration = entry.duration;
// 入力遅延(イベント処理前)
const delay = entry.processingStart - entry.startTime;
// 同期イベント処理時間
// (配信の開始と終了)
const eventHandlerTime = entry.processingEnd - entry.processingStart;
console.log(`Total duration: ${duration}`);
console.log(`Event delay: ${delay}`);
console.log(`Event handler duration: ${eventHandlerTime}`);
});
});
// イベントのオブザーバーを登録
observer.observe({ type: "event", buffered: true });
異なる durationThreshold
を設定することもできます。既定では 104ms で、最小可能な閾値は 16ms です。
observer.observe({ type: "event", durationThreshold: 16, buffered: true });
First Input Delay (FID) の報告
first input delay または FID は、ユーザーが最初にページを操作した時(つまり、リンクをクリックしたりボタンをタップしたりした時)から、その操作に応答してブラウザーが実際にイベントハンドラーの処理を始めることができるまでの時刻を測定します。
// Keep track of whether (and when) the page was first hidden, see:
// https://github.com/w3c/page-visibility/issues/29
// NOTE: ideally this check would be performed in the document <head>
// to avoid cases where the visibility state changes before this code runs.
let firstHiddenTime = document.visibilityState === "hidden" ? 0 : Infinity;
document.addEventListener(
"visibilitychange",
(event) => {
firstHiddenTime = Math.min(firstHiddenTime, event.timeStamp);
},
{ once: true },
);
// Sends the passed data to an analytics endpoint. This code
// uses `/analytics`; you can replace it with your own URL.
function sendToAnalytics(data) {
const body = JSON.stringify(data);
// Use `navigator.sendBeacon()` if available,
// falling back to `fetch()`.
(navigator.sendBeacon && navigator.sendBeacon("/analytics", body)) ||
fetch("/analytics", { body, method: "POST", keepalive: true });
}
// Use a try/catch instead of feature detecting `first-input`
// support, since some browsers throw when using the new `type` option.
// https://webkit.org/b/209216
try {
function onFirstInputEntry(entry) {
// Only report FID if the page wasn't hidden prior to
// the entry being dispatched. This typically happens when a
// page is loaded in a background tab.
if (entry.startTime < firstHiddenTime) {
const fid = entry.processingStart - entry.startTime;
// Report the FID value to an analytics endpoint.
sendToAnalytics({ fid });
}
}
// Create a PerformanceObserver that calls
// `onFirstInputEntry` for each entry.
const po = new PerformanceObserver((entryList) => {
entryList.getEntries().forEach(onFirstInputEntry);
});
// Observe entries of type `first-input`, including buffered entries,
// i.e. entries that occurred before calling `observe()` below.
po.observe({
type: "first-input",
buffered: true,
});
} catch (e) {
// Do nothing if the browser doesn't support this API.
}
仕様書
Specification |
---|
Event Timing API # sec-performance-event-timing |
ブラウザーの互換性
BCD tables only load in the browser