イベントタイミングAPI

W3C作業草案、

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-event-timing-20261013/
最新版:
https://www.w3.org/TR/event-timing/
編集者ドラフト:
https://w3c.github.io/event-timing/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/event-timing/
テストスイート:
https://github.com/web-platform-tests/wpt/tree/master/event-timing
フィードバック:
GitHub
編集者:
(Google)
以前の編集者:
(Google)
(Google)

概要

この文書は、ウェブページの制作者に対し、ユーザー操作によって発生する特定イベントのレイテンシを把握できるAPIを定義します。

この文書のステータス

このセクションは、本書が公開された時点でのステータスについて説明します。 最新のW3C出版物一覧や、この技術レポートの最新版は W3C標準・ドラフトのインデックスにて確認できます。

本書は Web Performance Working Group によって 作業草案(Working Draft)として、勧告トラックに従い公開されました。 作業草案として公開されたことは W3Cおよびその会員による承認を意味しません。

本書はドラフトであり、今後更新、置換、または廃止される可能性があります。 作業途上文書以外のものとして引用するのは不適切です。

GitHub Issuesはこの仕様について議論する際の推奨手段です。

本書は 2025年8月18日版 W3Cプロセス文書に従い管理されています。

本書は W3C特許ポリシーの下で活動するグループによって作成されました。 W3Cは グループの成果物に関連する特許開示の公開リストを管理しています。 このページには特許開示の方法についての説明も含まれています。 実際に特許に関する知識を持つ個人は、 その特許が必須クレームを含むと考える場合、 W3C特許ポリシー第6節に従って情報を開示しなければなりません。

1. はじめに

1.1. 概要

このセクションは規範的ではありません。

ユーザーがウェブサイトを操作する際、自分の行動によって素早くウェブサイトが変化することを期待しています。 実際、調査 によれば、ユーザー入力が100ms以内に処理されない場合は遅いとみなされます。 そのため、ガイドラインに達しなかった入力イベントについて、パフォーマンスタイミング情報を表面化することが重要です。

イベントの待ち時間を監視する一般的な方法は、イベントリスナーを登録することです。 イベントが生成されたタイムスタンプは、イベントのtimeStampで取得できます。 加えて、performance.now()は イベントハンドラーの処理開始時と終了時の両方で呼び出すことができます。 ハードウェアのタイムスタンプとイベントハンドラーの開始時に取得したタイムスタンプの差分で、 入力遅延(入力が処理され始めるまでの時間)を算出できます。 また、イベントハンドラー開始時と終了時のタイムスタンプの差分で、 イベントハンドラー内で同期的に行われた作業量を算出できます。 最後に、入力が同期的に処理された場合、イベント処理後の次回ペイントまでの期間はユーザー体験の指標として有用です。

この手法には根本的な欠陥がいくつかあります。 第一に、イベントリスナーの必須化によって、ページ読み込みの非常に早い段階でイベント遅延を計測することができなくなります——なぜなら、その時点でリスナーがまだ登録されていない場合があるからです。 第二に、入力遅延にだけ関心がある開発者であっても、元々リスナーがなかったイベントに新たにリスナーを追加せざるを得なくなります。 これによって、イベント遅延の計算に不要なパフォーマンス負荷がかかることになります。 さらに最後に、この手法ではイベントによって引き起こされた非同期処理の計測は非常に難しくなります。

この仕様は、イベント待ち時間の監視の代替手段を提供し、これらの問題の一部を解決します。 ユーザーエージェントがタイムスタンプを算出するため、パフォーマンス測定にイベントリスナーが不要です。 このため、ページロード非常に早期に発生したイベントも計測できます。 また、分析プロバイダがあらゆるイベントをパッチして購読しなくても、遅いイベントを可視化できます。 加えて、不要なイベントリスナーによるウェブサイトのパフォーマンス低下も防げます。 最後に、この仕様により、イベント処理直後のレンダリングタイミングの詳細情報も取得可能となり、 イベントによるウェブサイト変更のオーバーヘッド計測にも役立ちます。

1.2. インタラクション

この節は規範的ではありません。

単一のユーザーによる Interaction (ジェスチャーと呼ばれることもあります)は、通常、複数の物理的なハードウェア入力イベントで構成されます。 各物理入力イベントによって、ユーザーエージェントが複数の UIEvent をディスパッチする場合があり、 それぞれが複数のカスタムイベントリスナーを呼び出したり、異なる既定のアクションを引き起こしたりする場合があります。

例えば、タッチスクリーンデバイスでの単一のユーザーによる「タップ」インタラクションは、実際には一連 の物理入力イベントで構成されます。

これらの物理入力イベントは、一連の UIEvent をディスパッチする場合があります。

これら個々の UIEvent は、 それぞれ独自の PerformanceEventTiming エントリーとして報告される候補となり、詳細なタイミングの把握に役立ちます。

注記: pointermove および touchmove は現在、Event Timing の対象として考慮されていません。

ただし、この仕様では、関連する PerformanceEventTiming を 一つの Interaction に まとめるための interactionId を使った仕組みも定義しています。 この仕組みは、ページの応答性の指標である 次の描画までの インタラクション(INP) を定義するために使用できます。

1.3. 最初の入力

このセクションは規範的ではありません。

最初のユーザーInteraction は、ユーザー体験に格段に大きな影響を与えることが多く、また非常に遅くなりがちです。

このため、Event Timing APIはWindowの最初の入力に関するタイミング情報を公開します。 これは、非0のinteractionIdを持つ最初のPerformanceEventTimingエントリとして定義されます。

通常のPerformanceEventTimingエントリと異なり、 最初の入力エントリは、指定されたdurationThresholdを超えなくても報告され、 デフォルトの104msのduration thresholdを超えなくてもバッファリングされます。 この仕組みは、ページ応答性指標 First Input Delay (FID)の定義に利用できます。

また、イベントハンドラー登録不要でも、常に非常に応答性が高いページも含めてデータ取得できるため、パーセンタイルやパフォーマンス改善の計測にも役立ちます。

1.4. 公開されるイベント

Event Timing APIは特定のイベントのみタイミング情報を公開します。

指定された event が Event Timing の対象として考慮されるかどうかを判定するには、次の 手順を実行します。
  1. event の isTrusted 属性値が false に設定されている場合、false を返します。

  2. event の type が次のいずれかである場合: auxclick, click, contextmenu, dblclick, mousedown, mouseenter, mouseleave, mouseout, mouseover, mouseup, pointerover, pointerenter, pointerdown, pointerup, pointercancel, pointerout, pointerleave, gotpointercapture, lostpointercapture, touchstart, touchend, touchcancel, keydown, keypress, keyup, beforeinput, input, compositionstart, compositionupdate, compositionend, dragstart, dragend, dragenter, dragleave, dragover, drop, true を返します。

  3. false を返します。

注記: mousemove, pointermove, pointerrawupdate, touchmove, wheel, および drag は「連続的」なイベントであるため除外されます。 現在の API には、これらのイベントをどのように計数および集約して、 エントリーに基づく有意義なパフォーマンス指標を得るかについて十分な指針がありません。 そのため、これらのイベント型は公開されません。

1.5. イベントが測定されるタイミング

このセクションは規範的ではありません。 § 3 処理モデルセクションで公開される情報の概要を説明します。

イベントタイミング情報は特定のイベントのみ公開され、ユーザー入力とその後のペイント操作までの時間差が所定のduration thresholdを超えた場合のみ公開されます。

Event Timing APIは、物理的なユーザー入力発生時点(Eventの timeStampで推定)から、 Eventの 関連グローバルオブジェクトの関連付けられたDocumentのレンダリング更新までの時間を duration値として公開します。 この値は8ミリ秒単位で提供されます。

デフォルトでは、Event Timing APIはduration が104以上の場合のみエントリをバッファリング・公開しますが、開発者はPerformanceObserverで 別のしきい値を設定可能です。 ただし、これはバッファリングされるエントリには影響せず、bufferedフラグは デフォルトしきい値以上の過去エントリのみ受け取るために使われます。

Eventの delayは、ブラウザがイベントハンドラーを実行しようとする時刻とEventの timeStampとの差分です。 前者はPerformanceEventTimingの processingStartで、 後者はPerformanceEventTimingのstartTimeで公開されます。 よって、Eventの delayはprocessingStart - startTimeで計算できます。

Event Timing APIはイベントリスナー有無に関わらずエントリを生成します。 特に、最初のクリックや最初のキー入力は、ページ機能に実際にアクセスしようとしたものとは限りません。 ユーザーはテキスト選択や空白領域クリックなどをよく行います。 これは、イベントリスナー登録が遅すぎるページの問題や、イベントリスナーがなくても意味がある入力(ホバー効果等)のパフォーマンスも捉えるための設計方針です。 開発者はprocessingEnd - processingStartがほぼゼロのエントリを無視することで、 実質的に処理されていない入力を除外できます。 processingEndは イベント発行アルゴリズムが終了した時刻です。

1.6. 使用例

const observer = new PerformanceObserver(function(list, obs) {
    for (let entry of list.getEntries()) {
        // 入力遅延
        const inputDelay = entry.processingStart - entry.startTime;
        // 処理時間
        const processingDuration = entry.processingEnd - entry.processingStart;
        // 表示遅延 (概算)
        const presentationDelay = Math.max(0, entry.startTime + entry.duration - entry.processingEnd);

        // このイベントのtargetに関する情報(例えばid)を取得
        const targetId = entry.target ? entry.target.id : 'unknown-target';

        console.log(entry.entryType, entry.name, entry.duration, { inputDelay, processingDuration, presentationDelay });
    }
});
observer.observe({ type: 'first-input', buffered: true });
observer.observe({ type: 'event', buffered: true, durationThreshold: 40 });

次の例は、interactionId ごとのイベント最大durationを辞書として計算します。 この辞書は集計してアナリティクスに報告することができます。

let maxDurations = {};
new PerformanceObserver(list => {
    for (let entry of list.getEntries()) {
        if (entry.interactionId > 0) {
            let id = entry.interactionId;
            if (!maxDurations[id]) {
                maxDurations[id] = entry.duration;
            } else {
                maxDurations[id] = Math.max(maxDurations[id], entry.duration);
            }
        }
    }
}).observe({ type: 'event', buffered: true, durationThreshold: 16 });

このAPIを利用して達成できるユースケース例:

2. イベントタイミング

イベントタイミングは以下のインターフェイスを追加します:

2.1. PerformanceEventTiming インターフェイス

[Exposed=Window]
interface PerformanceEventTiming : PerformanceEntry {
    readonly attribute DOMHighResTimeStamp processingStart;
    readonly attribute DOMHighResTimeStamp processingEnd;
    readonly attribute boolean cancelable;
    readonly attribute Node? target;
    readonly attribute DOMString targetSelector;
    readonly attribute unsigned long long interactionId;
    [Default] object toJSON();
};

PerformanceEventTiming オブジェクトは、ひとつの対応するEventの タイミング情報を報告します。

各PerformanceEventTiming オブジェクトには、以下の関連する概念があり、すべて初期値はnullです:

target 属性のgetterは以下の手順を実行します:

  1. thisのeventTargetについて、文書引数に null を指定して paint timing用に公開されるか判定した結果が偽なら、nullを返す。

  2. thisのeventTargetを返す。

注: Event Timing APIを実装するユーザーエージェントは first-inputとeventをsupportedEntryTypes に含める必要があります(Windowコンテキスト)。 これにより、開発者はイベントタイミングのサポートを検知できます。

このセクションの残りは規範的ではありません。 PerformanceEventTiming 属性値は§ 3 処理モデルで設定されます。 ここではそれらがどのように設定されるかの説明をまとめています。

PerformanceEventTiming は、PerformanceEntry インターフェイスの以下の属性を拡張します:

name
name 属性のgetterは、対応するイベントのtypeを返します。
entryType
entryType 属性のgetterは「event」(長いイベントの場合)または「first-input」(最初のユーザー操作の場合)を返します。
startTime
startTime 属性のgetterは、対応するイベントのtimeStampを返します。
duration
duration 属性のgetterは、レンダリング更新が 対応するイベントのDocumentで 対応するイベントが配送された後に次に完了した時刻とstartTimeの差分(8ms単位で丸め)を返します。

PerformanceEventTiming には以下の追加属性があります:

processingStart
processingStart 属性のgetterは イベント発行アルゴリズムの開始時点のタイムスタンプ(イベントハンドラー実行直前)を返します。
processingEnd
processingEnd 属性のgetterは イベント発行アルゴリズムの終了時点のタイムスタンプ(イベントハンドラー実行完了)を返します。イベントハンドラーがなければprocessingStartと同じです。
cancelable
cancelable 属性のgetterは 対応するイベントの cancelable属性値を返します。
target
target 属性のgetterは、対応するイベントの最後のtarget(そのNodeが切断されておらず、shadow DOMでもない場合)を返します。
targetSelector
targetSelector 属性のgetterは、文字列を返す。これは、関連付けられたイベントの最後の target を識別する。
interactionId
interactionId 属性のgetterは、 関連付けられたイベントを発生させたユーザー Interaction を一意に識別する番号を返す。 この属性は、関連付けられたイベントの type 属性値が以下のいずれかでない限り、0である。
  • ある pointerdown, pointerup, または click であり、タップまたはドラッグのジェスチャーに属します。なお、pointerdown のうち、スクロールに至るものは除外されます。

  • ある keydown または keyup であり、ユーザーによるキー押下に属します。

2.2. EventCounts インターフェイス

[Exposed=Window]
interface EventCounts {
    readonly maplike<DOMString, unsigned long long>;
};

EventCounts オブジェクトは、キーがイベントの type 、値がその type の 発火したイベント数となるマップである。 このマップでカウントされるのは、 type が PerformanceEventTiming エントリ(§ 1.4 公開されるイベント参照)でサポートされているイベントのみである。

2.3. Performance インターフェイスへの拡張

[Exposed=Window]
partial interface Performance {
    [SameObject] readonly attribute EventCounts eventCounts;
    readonly attribute unsigned long long interactionCount;
};

eventCounts 属性のgetterは、thisの関連グローバルオブジェクトのeventCountsを返します。

interactionCount 属性のgetterは、thisの関連グローバルオブジェクトのinteractionCountを返します。

3. 処理モデル

3.1. DOM仕様への変更

このセクションは[DOM]が変更されたら削除されます。

イベント発行アルゴリズムを以下のように変更します。

ステップ1直後に、次のステップを追加します:

  1. eventに対し、interactionIdを計算した結果をinteractionIdとする。

  2. event、現在の高精度時刻、およびinteractionIdを用いて、イベントタイミングを初期化した結果をtimingEntryとする。

アルゴリズムの戻り値を返す直前に、次のステップを追加します:

  1. イベントタイミングの完了処理を、 timingEntry、event、target、現在の高精度時刻を引数として呼び出す。

注: ユーザーエージェントがイベント発行アルゴリズムを省略する場合でも、 そのEventについて エントリを追加することが可能です。 この場合、processingStartの値を推定し、 processingEnd には同じ値を設定します。

3.2. HTML仕様への変更

このセクションは[HTML]が変更されたら削除されます。

各Window には以下の関連する概念があります:

レンダリング更新ステップで、イベントループ処理モデルの paint timingのマーク呼び出し直後に、次のステップを追加します:
  1. 各docs内の完全にアクティブなDocument について、そのDocumentの保留中のイベントタイミングエントリの発行アルゴリズムを呼び出す。

3.3. Performance Timeline仕様への変更

このセクションは[PERFORMANCE-TIMELINE-2]が変更されたら削除されます。

PerformanceObserverInit 辞書が拡張されます:

partial dictionary PerformanceObserverInit {
    DOMHighResTimeStamp durationThreshold;
};

3.4. PerformanceEventTiming追加判定

注: 以下のアルゴリズムは[PERFORMANCE-TIMELINE-2]仕様で、 PerformanceEventTiming エントリをPerformanceObserver のバッファまたはパフォーマンスタイムラインに追加する必要があるかどうか(レジストリ参照)を決定する際に使用されます。

PerformanceEventTiming entryとPerformanceObserverInit optionsを入力として、 PerformanceEventTiming追加判定を行うには、以下の手順を実行します:
  1. entryのentryType 属性値が"first-input"の場合、trueを返す。

  2. entryのentryType 属性値が"event"であることを確認(assert)する。

  3. minDurationを以下のように計算する:

    1. optionsが未指定、またはoptionsのdurationThreshold が未指定の場合、minDurationは104とする。

    2. そうでなければ、minDurationは16とoptionsのdurationThreshold の値の最大値とする。

  4. entryのduration 属性値がminDuration以上の場合、trueを返す。

  5. そうでなければfalseを返す。

3.5. インタラクション数の増加

Window 型のwindowオブジェクトに対し、インタラクション数の増加を求められた場合、次の手順を実行する:
  1. windowのユーザーインタラクション値を、ユーザーエージェントが選択した少量だけ増加させる。

  2. interactionCountをwindowのinteractionCountとする。

  3. interactionCountをinteractionCount+1に設定する。

注: ユーザーインタラクション値は1ではなくユーザーエージェントが選択した少量だけ増加させる。これにより、開発者がウェブアプリケーションで発生したインタラクション数のカウンターとして誤用しにくくしている。 ユーザーエージェントはポインター押下時に積極的にユーザーインタラクション値を割り当て、例えばpointercancel後に破棄することもできる(遅延計算ではなく即時割り当て)。

ユーザーエージェントは毎回小さなランダム整数で増加させてもよいし、一定値でもよい。 ただしユーザーエージェントは、すべてのWindowで共有されたグローバルなユーザーインタラクション値を使ってはいけない。これはクロスオリジン情報漏洩の原因となる可能性があるためである。

3.6. interactionIdの算出

要求された場合、interactionId を 計算するには、event を入力として次の手順を実行します。
  1. event の isTrusted 属性値が false の場合、0 を返します。

  2. type を event の type 属性値とします。

  3. type が次の keyup, compositionstart, input, pointercancel, pointerup, click, または contextmenu のいずれでもない場合、0 を返します。

    注記: keydown および pointerdown は イベントタイミングの確定時に保留としてマークされ、その後、 将来のイベント(例えば keyup や pointerup)について interactionId を計算する際に更新されます。

  4. window を event の 関連するグローバルオブジェクトとします。

  5. pendingKeyDowns を window の 保留中のキーダウンとします。

  6. pointerMap を window の ポインター インタラクション値マップとします。

  7. pendingPointerDowns を window の 保留中のポインターダウンとします。

  8. type が keyup の場合:

    1. event の isComposing 属性値が true の場合、0 を返します。

    2. code を event の keyCode 属性値とします。

    3. pendingKeyDowns[code] が存在しない場合、0 を返します。

    4. entry を pendingKeyDowns[code] とします。

    5. インタラクション数を増加させる操作を window に対して実行します。

    6. interactionId を window の ユーザーインタラクション 値の値とします。

    7. entry の interactionId を interactionId に設定します。

    8. entry を window の キューに追加される エントリーに追加します。

    9. pendingKeyDowns[code] を 削除します。

    10. interactionId を返します。

  9. type が compositionstart の場合:

    1. pendingKeyDowns の 値に含まれる各 entry について:

      1. entry を window の キューに追加される エントリーに追加します。

    2. pendingKeyDowns を クリアします。

    3. 0 を返します。

  10. type が input の場合:

    1. event が InputEvent のインスタンスでない場合、 0 を返します。 注記:この検査は、Events のうち、 type が input であっても、 テキスト内容の変更に関係しないものを除外するために行われます。

    2. event の isComposing 属性値が false の場合、0 を返します。

    3. インタラクション数を増加させる操作を window に対して実行します。

    4. window の ユーザーインタラクション値を返します。

  11. それ以外の場合(type が pointercancel, pointerup, click, または contextmenu の場合):

    1. pointerId を event の pointerId 属性値とします。

    2. type が click の場合:

      1. pointerMap[pointerId] が存在しない場合、0 を返します。

      2. value を pointerMap[pointerId] とします。

      3. pointerMap[pointerId] を削除します。

      4. value を返します。

    3. type が pointerup, pointercancel, または contextmenu であることを表明します。

    4. pendingPointerDowns[pointerId] が存在しない場合:

      1. type が contextmenu の場合、 window の ユーザー インタラクション値を返します。

      2. type が pointerup であり、window の contextmenu が発生したかフラグが true の場合:

        1. window の contextmenu が発生したか フラグを false に設定します。

        2. window の ユーザーインタラクション値を返します。

      3. それ以外の場合、0 を返します。

    5. pointerDownEntry を pendingPointerDowns[pointerId] とします。

    6. pointerDownEntry が PerformanceEventTiming エントリーであることを表明します。

    7. type が pointerup または contextmenu の場合:

      1. インタラクション数を増加させる操作を window に対して実行します。

      2. pointerMap[pointerId] を window の ユーザーインタラクション値に設定します。

      3. pointerDownEntry の interactionId を pointerMap[pointerId] に設定します。

    8. pointerDownEntry を window の キューに追加される エントリーに追加します。

    9. pendingPointerDowns[pointerId] を削除します。

    10. type が contextmenu の場合、 window の contextmenu が発生したかを true に設定します。

    11. type が pointercancel の場合、 0 を返します。

    12. pointerMap[pointerId] を返します。

注記: このアルゴリズムは、イベントに 対応するインタラクション ID を割り当てようとします。 キーボードイベントの場合、keydown によって新しいインタラクション ID が生成されますが、keyup はその ID を以前の keydown の ID と一致させる必要があります。 ポインターイベントの場合、pointerdown を受け取ったとき、 その pointercancel または pointerup が発生するまで待ってから、その interactionId を知る必要があります。 また、click を以前の pointerdown のインタラクション ID と一致させようとします。 pointercancel または pointerup が発生すると、保存されている interactionId を pointerdown に対応するエントリーに設定できるようになります。 それが pointercancel の場合、 pointerdown に新しいインタラクション ID を割り当てないことを意味します。 それが pointerup の場合、 新しいインタラクション ID を計算し、pointerdown と pointerup の両方(さらに後で click が発生した場合はそれにも)設定します。

3.7. イベントタイミングの初期化

イベントタイミングの初期化を、event、processingStart、interactionIdを入力として求められた場合、以下の手順を実行する:
  1. アルゴリズム「eventがEvent Timingの対象かどうか」を実行してfalseなら、nullを返す。

  2. timingEntryをeventの関連realmで新しいPerformanceEventTimingオブジェクトとして生成。

  3. timingEntryのnameにeventのtype属性値を設定。

  4. timingEntryのentryTypeに"event"を設定。

  5. timingEntryのstartTimeにeventのtimeStamp属性値を設定。

  6. timingEntryのprocessingStartにprocessingStartを設定。

  7. timingEntryのcancelableにeventのcancelable属性値を設定。

  8. timingEntryのinteractionIdにinteractionIdを設定。

  9. timingEntryを返す。

3.8. イベントタイミングの完了

イベントタイミングを確定するよう要求されたときは、入力として timingEntry、event、target、processingEnd を受け取り、次の手順を実行する:
  1. もし timingEntry が null なら、return する。

  2. relevantGlobal を target の 関連するグローバルオブジェクトとする。

  3. もし relevantGlobal が implements Window でないなら、return する。

  4. timingEntry の processingEnd に processingEnd を設定する。

  5. Assert: target が implements Node である。

    注: このアサーションは Event Timing API がサポートするイベント型によって保証される。

  6. timingEntry の関連付けられた eventTarget に target を設定する。

    注: これにより eventTarget は最後のイベントターゲットになる。retargeting が発生した場合、root に最も近い最後のターゲットが使われる。

  7. timingEntry の targetSelector に、target を入力として CSSセレクター生成アルゴリズムを実行した結果を設定する。

  8. event の type 属性値が pointerdown の場合:

    1. pendingPointerDowns を relevantGlobal の 保留中pointerdownとする。

    2. pointerId を event の pointerId とする。

    3. もし pendingPointerDowns[pointerId] が存在するなら:

      1. previousPointerDownEntry を pendingPointerDowns[pointerId] とする。

      2. previousPointerDownEntry を relevantGlobal の キューされるエントリに追加する。

    4. pendingPointerDowns[pointerId] に timingEntry を設定する。

    5. relevantGlobal の is contextmenu triggered を false に設定する。

  9. それ以外で、event の type 属性値が keydown である場合:

    1. もし event の isComposing 属性値が true なら:

      1. timingEntry を relevantGlobal の キューされるエントリに追加する。

      2. return する。

    2. pendingKeyDowns を relevantGlobal の 保留中keydownとする。

    3. code を event の keyCode 属性値とする。

    4. もし pendingKeyDowns[code] が存在するなら:

      1. previousKeyDownEntry を pendingKeyDowns[code] とする。

      2. code が 229 でない場合:

        1. relevantGlobal の ユーザー操作値 をユーザーエージェントが選択した小さな値だけ増加させる。

        2. previousKeyDownEntry の interactionId を relevantGlobal の ユーザー操作値 に設定する。

        注: 229はIMEキーボードイベントに該当する特別なケース。ユーザーエージェントから複数回送信される場合があり、キーの長押しとは対応しない場合もある。

      3. previousKeyDownEntry を relevantGlobal の キューされるエントリに追加する。

    5. pendingKeyDowns[code] に timingEntry を設定する。

  10. それ以外の場合:

    1. timingEntry を relevantGlobal の キューされるエントリに追加する。

3.9. 保留中のイベントタイミングエントリの発行

保留中のイベントタイミングエントリの発行を、Document 型のdocについて求められた場合、以下の手順を実行する:
  1. windowをdocの関連グローバルオブジェクトとする。

  2. renderingTimestampを現在の高精度時刻とする。

  3. windowのエントリのキュー待ちリスト内の各timingEntryについて:

    1. イベントタイミングエントリのduration設定を、timingEntry、window、renderingTimestampを入力として実行。

    2. timingEntryのduration属性値が16以上なら、timingEntryをキューする。

  4. window の キューされるエントリ を空のリストに設定する。

  5. windowの保留中のポインター押下の値ごとにpendingPointerDownEntryについて:

    1. イベントタイミングエントリのduration設定を、pendingPointerDownEntry、window、renderingTimestampを入力として実行。

  6. windowの保留中のキー押下の値ごとにpendingKeyDownEntryについて:

    1. イベントタイミングエントリのduration設定を、pendingKeyDownEntry、window、renderingTimestampを入力として実行。

イベントタイミングエントリのduration設定を、PerformanceEventTiming 型のtimingEntry、Window 型のwindow、DOMHighResTimeStamp 型のrenderingTimestampを入力として求められた場合、以下の手順を実行する:
  1. timingEntryのduration属性値が0以外ならreturn。

  2. startをtimingEntryのstartTime属性値とする。

  3. timingEntryのdurationに、DOMHighResTimeStampとしてrenderingTimestamp - start(8ms以下の粒度)を設定。

  4. nameをtimingEntryのname属性値とする。

  5. 以下の手順でイベント数を更新:

    1. eventCountsをwindowのeventCountsとする。

    2. eventCountsがnameを含むことを確認。

    3. eventCounts[name]をeventCounts[name]+1に設定。

  6. windowの入力イベント発行済フラグがfalseで、timingEntryのinteractionIdが0でなければ、以下の手順を実行:

    1. firstInputEntryをtimingEntryのコピーとする。

    2. firstInputEntryのentryTypeに"first-input"を設定。

    3. firstInputEntryをキューする。

    4. windowの入力イベント発行済フラグをtrueに設定。

3.10. ターゲットセレクター

CSSセレクターを生成するためには、EventTarget target を受け取り、以下の手順を実行する:
  1. もし target が Node であれば、次の手順を実行する:

    1. selector を、初期値として target の nodeName の文字列で設定する。

    2. もし target が Element であれば、次の手順を実行する:

      1. もし target が `id` 属性を持つなら、selector を « selector、"#"、`id` 属性の値 » の連結で設定する。

      2. それ以外で target が `src` 属性を持つなら、selector を « selector、"[src="、`src` 属性の値、"]" » の連結で設定する。

    3. selector を返す。

  2. それ以外の場合、空文字列を返す。

4. セキュリティおよびプライバシーに関する考慮事項

高精度タイマーをウェブプラットフォームに追加することは、セキュリティ上の懸念があるため望ましくありません。 イベントハンドラーのタイムスタンプは、performance.now()と同じ精度です。 processingStart やprocessingEnd はこのAPIを使わなくても算出可能なので、 これら属性を公開することが新たな攻撃面を生むことはありません。 よって、duration のみが追加の考慮を要します。

duration は8ミリ秒の粒度を持ちます(丸め処理によってそのように計算されます)。 そのため、これらのタイムスタンプから高精度タイマーを生成することはできません。 しかし、この仕様はウェブ開発者にとって簡単には得られない新たな情報――イベント処理後にピクセルが描画されるまでの時間――を導入します。 粒度を考慮し、このタイムスタンプを公開することにセキュリティやプライバシー上の懸念はないと考えています。 有用かつ最小限の新情報のみを公開する観点から、粒度として8ミリ秒を選択しました。 これによって、120Hzディスプレイでも比較的精密なタイミングを得られます。

duration のデフォルト閾値104msは、100msを超える最初の8の倍数です。 丸め前のdurationが100ms以上であれば、丸め結果も104ms以上となります。 このようなイベントは100ms以内に処理されず、ユーザー体験に悪影響を及ぼす可能性があります。

durationThreshold の最小値16msは、 応答が滑らかであることを保証する一般的なユースケースのためです。120Hzディスプレイでは、1フレーム以上スキップする応答は16ms以上となり、 この値以上のユーザー入力はAPIで取得できます。

適合性

文書の慣例

適合要件は記述的な断言およびRFC 2119の用語の組み合わせで表現されます。 規範部分で使用される “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” などのキーワードはRFC 2119の定義に従って解釈されます。 ただし可読性のため、本仕様ではすべて大文字では記述しません。

明示的に非規範と記載された部分、例、注釈以外は本仕様のすべてが規範です。[RFC2119]

本仕様の例は “for example” という語句で導入されるか、 または以下のように規範文からclass="example" で区別されます:

これは参考例の一例です。

参考注釈は “Note” で始まり、 または以下のように規範文からclass="note" で区別されます:

注:これは参考注釈です。

適合アルゴリズム

アルゴリズムで命令形で記載された要件(例:「先頭の空白文字を除去する」「falseを返して処理を中断する」など)は、 アルゴリズム導入時のキーワード(must, should, may など)の意味で解釈されます。

アルゴリズムや具体的な手順として記載された適合要件は、 結果が同等であればどのような方法でも実装可能です。 特に本仕様で定義されたアルゴリズムは理解しやすさを重視しており、パフォーマンスのためのものではありません。 実装者は最適化することが推奨されています。

索引

本仕様で定義されている用語

他の仕様で定義されている用語

参考文献

規定参考文献

[DOM]
Anne van Kesteren. DOM標準. 現行標準。 URL: https://dom.spec.whatwg.org/
[HR-TIME-2]
Ilya Grigorik. 高精度時間レベル2. 21日 2019年11月。REC。URL: https://www.w3.org/TR/hr-time-2/
[HTML]
Anne van Kesteren; ほか。HTML標準。 現行標準。URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 標準。現行標準。URL: https://infra.spec.whatwg.org/
[PAINT-TIMING]
Ian Clelland; Noam Rosenthal. 描画タイミング。2日 2026年10月。WD。URL: https://www.w3.org/TR/paint-timing/
[PERFORMANCE-TIMELINE-2]
Nicolas Pena Moreno. パフォーマンス タイムライン。2025年5月21日。CRD。URL: https://www.w3.org/TR/performance-timeline/
[POINTEREVENTS4]
Patrick Lauke; Robert Flack. ポインター イベント。2026年10月8日。WD。URL: https://www.w3.org/TR/pointerevents4/
[RFC2119]
S. Bradner. RFCで要件レベルを 示すためのキーワード。1997年3月。現行のベストプラクティス。URL: https://datatracker.ietf.org/doc/html/rfc2119
[TOUCH-EVENTS]
Doug Schepers; ほか。タッチイベント。10日 2013年10月。REC。URL: https://www.w3.org/TR/touch-events/
[UIEVENTS]
Xiaoqian Wu. UIイベント。2026年2月21日。WD。 URL: https://www.w3.org/TR/uievents/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL標準。現行 標準。URL: https://webidl.spec.whatwg.org/

IDL索引

[Exposed=Window]
interface PerformanceEventTiming : PerformanceEntry {
    readonly attribute DOMHighResTimeStamp processingStart;
    readonly attribute DOMHighResTimeStamp processingEnd;
    readonly attribute boolean cancelable;
    readonly attribute Node? target;
    readonly attribute DOMString targetSelector;
    readonly attribute unsigned long long interactionId;
    [Default] object toJSON();
};

[Exposed=Window]
interface EventCounts {
    readonly maplike<DOMString, unsigned long long>;
};

[Exposed=Window]
partial interface Performance {
    [SameObject] readonly attribute EventCounts eventCounts;
    readonly attribute unsigned long long interactionCount;
};

partial dictionary PerformanceObserverInit {
    DOMHighResTimeStamp durationThreshold;
};

MDN

EventCounts

Firefox89+SafariNoneChrome85+
Opera?Edge85+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Performance/eventCounts

Firefox89+SafariNoneChrome85+
Opera?Edge85+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.jsNone
MDN

PerformanceEventTiming/cancelable

Firefox89+SafariNoneChrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
⚠MDN

PerformanceEventTiming/interactionId

In only one current engine.

FirefoxNoneSafariNoneChrome96+
Opera?Edge96+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceEventTiming/processingEnd

Firefox89+SafariNoneChrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceEventTiming/processingStart

Firefox89+SafariNoneChrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceEventTiming/target

Firefox89+SafariNoneChrome85+
Opera?Edge85+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceEventTiming/toJSON

Firefox89+SafariNoneChrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceEventTiming

Firefox89+SafariNoneChrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?