イベントタイミングAPI

W3C作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2025/WD-event-timing-20251017/
最新版:
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エントリ報告対象となります。

注: pointermovetouchmove は現時点ではEvent Timingの対象ではありません。

ただし、本仕様では関連するPerformanceEventTimingInteractioninteractionIdを使ってグループ化する仕組みも定義しています。 この仕組みはページ応答性指標 Interaction to Next Paint (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. eventisTrusted 属性値がfalseの場合、falseを返す。

  2. eventtype が以下のいずれかの場合:auxclickclickcontextmenudblclickmousedownmouseentermouseleavemouseoutmouseovermouseuppointeroverpointerenterpointerdownpointeruppointercancelpointeroutpointerleavegotpointercapturelostpointercapturetouchstarttouchendtouchcancelkeydownkeypresskeyupbeforeinputinputcompositionstartcompositionupdatecompositionenddragstartdragenddragenterdragleavedragoverdrop、 trueを返す。

  3. falseを返す。

注: mousemovepointermovepointerrawupdatetouchmovewheeldrag は「連続的」イベントであるため除外されています。 現在のAPIではこれらイベントのカウントや集計に関する十分なガイダンスがなく、エントリに基づく有意なパフォーマンス指標を得ることが困難なため、これらのイベントタイプは公開されません。

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

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

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

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

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

Eventdelayは、ブラウザがイベントハンドラーを実行しようとする時刻とEventtimeStampとの差分です。 前者はPerformanceEventTimingprocessingStartで、 後者は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. thiseventTargetが、nullで paint timing用に公開されていなければ、nullを返す。

  2. thiseventTargetを返す。

注: Event Timing APIを実装するユーザーエージェントは first-inputeventsupportedEntryTypes に含める必要があります(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である。
  • pointerdownpointerupclick のいずれかで、タップやドラッグジェスチャに属するもの(ただしpointerdownでスクロールに終わるものは除外)。

  • keydown またはkeyup で、ユーザーのキープレスに属するもの。

2.2. EventCounts インターフェイス

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

EventCounts オブジェクトは、キーがイベントタイプ、値がそのtypeで発行されたイベント数の マップです。 PerformanceEventTiming エントリでサポートされるtype§ 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. イベントタイミングの完了処理を、 timingEntryeventtarget現在の高精度時刻を引数として呼び出す。

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

3.2. HTML仕様への変更

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

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

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

3.3. Performance Timeline仕様への変更

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

PerformanceObserverInit 辞書が拡張されます:

partial dictionary PerformanceObserverInit {
    DOMHighResTimeStamp durationThreshold;
};

3.4. PerformanceEventTiming追加判定

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

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

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

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

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

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

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

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

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

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

  2. interactionCountwindowinteractionCountとする。

  3. interactionCountinteractionCount+1に設定する。

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

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

3.6. interactionIdの算出

eventを入力としてinteractionIdの算出を求められた場合、次の手順を実行する:
  1. eventisTrusted 属性値がfalseなら0を返す。

  2. typeeventtype属性値とする。

  3. typekeyupcompositionstartinputpointercancelpointerupclick、 またはcontextmenuのいずれでもない場合、0を返す。

    注: keydownpointerdownイベントタイミングの完了処理でpendingとされ、後からinteractionIdの算出で後続イベント(keyupやpointerupなど)のために更新される。

  4. windowevent関連グローバルオブジェクトとする。

  5. pendingKeyDownswindow保留中のキー押下とする。

  6. pointerMapwindowポインターインタラクション値マップとする。

  7. pendingPointerDownswindow保留中のポインター押下とする。

  8. typekeyupの場合:

    1. eventisComposing 属性値がtrueなら0を返す。

    2. codeeventkeyCode属性値とする。

    3. pendingKeyDowns[code]が存在しなければ0を返す。

    4. entrypendingKeyDowns[code]とする。

    5. windowに対しインタラクション数の増加を行う。

    6. interactionIdwindowユーザーインタラクション値とする。

    7. entryinteractionIdinteractionIdに設定する。

    8. entrywindowエントリのキュー待ちリストに追加する。

    9. pendingKeyDowns[code]を削除する。

    10. interactionIdを返す。

  9. typecompositionstartの場合:

    1. pendingKeyDownsごとにentryについて:

      1. entrywindowエントリのキュー待ちリストに追加する。

    2. pendingKeyDownsをクリアする。

    3. 0を返す。

  10. typeinputの場合:

    1. eventInputEventのインスタンスでなければ0を返す。 注:このチェックにより、typeがinputでもテキスト内容変更と関係ないイベントを除外する。

    2. eventisComposing 属性値がfalseなら0を返す。

    3. windowに対しインタラクション数の増加を行う。

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

  11. それ以外の場合(typepointercancelpointerupclick、 またはcontextmenuの場合):

    1. pointerIdeventpointerId属性値とする。

    2. typeclickの場合:

      1. pointerMap[pointerId]が存在しなければ0を返す。

      2. valuepointerMap[pointerId]とする。

      3. pointerMap[pointerId]を削除する。

      4. valueを返す。

    3. typepointeruppointercancel、 またはcontextmenuであることを確認する。

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

      1. typecontextmenuの場合、windowユーザーインタラクション値を返す。

      2. typepointerupwindowcontextmenu発行済フラグがtrueの場合:

        1. windowcontextmenu発行済フラグをfalseに設定する。

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

      3. それ以外は0を返す。

    5. pointerDownEntrypendingPointerDowns[pointerId]とする。

    6. pointerDownEntryPerformanceEventTimingエントリであることを確認する。

    7. typepointerupまたはcontextmenuの場合:

      1. windowに対しインタラクション数の増加を行う。

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

      3. pointerDownEntryinteractionIdpointerMap[pointerId]に設定する。

    8. pointerDownEntrywindowエントリのキュー待ちリストに追加する。

    9. pendingPointerDowns[pointerId]を削除する。

    10. typecontextmenuの場合、windowcontextmenu発行済フラグをtrueに設定する。

    11. typepointercancelの場合、0を返す。

    12. pointerMap[pointerId]を返す。

注: このアルゴリズムはイベントを対応するインタラクションIDに割り当てようとする。 キーボードイベントでは、keydown で新しいインタラクションIDが発生し、keyup は前のkeydownとID一致させる必要がある。 ポインターイベントでは、pointerdown ではpointercancelpointerup 発生までIDが確定しない。 click は直前のpointerdownのIDと一致させる。 pointercancelpointerup が起きれば、pointerdownに対応するエントリのIDを設定できる。 pointercancelなら、pointerdownに新しいIDは割り当てない。 pointerupなら新IDを計算し、pointerdownpointerup両方に設定する(その後clickにも設定可能)。

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

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

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

  3. timingEntrynameeventtype属性値を設定。

  4. timingEntryentryTypeに"event"を設定。

  5. timingEntrystartTimeeventtimeStamp属性値を設定。

  6. timingEntryprocessingStartprocessingStartを設定。

  7. timingEntrycancelableeventcancelable属性値を設定。

  8. timingEntryinteractionIdinteractionIdを設定。

  9. timingEntryを返す。

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

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

  2. relevantGlobaltarget関連するグローバルオブジェクトとする。

  3. もし relevantGlobalimplements Window でないなら、return する。

  4. timingEntryprocessingEndprocessingEnd を設定する。

  5. Assert: targetimplements Node である。

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

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

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

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

  8. もし eventtype 属性値が pointerdown である場合:

    1. pendingPointerDownsrelevantGlobal保留中pointerdownとする。

    2. pointerIdeventpointerId とする。

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

      1. previousPointerDownEntrypendingPointerDowns[pointerId] とする。

      2. previousPointerDownEntryrelevantGlobalキューされるエントリに追加する。

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

    5. windowis contextmenu triggered を false に設定する。

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

    1. もし eventisComposing 属性値が true なら:

      1. timingEntryrelevantGlobalキューされるエントリに追加する。

      2. return する。

    2. pendingKeyDownsrelevantGlobal保留中keydownとする。

    3. codeeventkeyCode 属性値とする。

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

      1. previousKeyDownEntrypendingKeyDowns[code] とする。

      2. code が 229 でない場合:

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

        2. previousKeyDownEntryinteractionIdwindowユーザー操作値 に設定する。

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

      3. previousKeyDownEntrywindowキューされるエントリに追加する。

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

  10. それ以外の場合:

    1. timingEntryrelevantGlobalキューされるエントリに追加する。

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

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

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

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

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

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

  4. windowエントリのキュー待ちリストをクリアする。

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

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

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

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

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

  2. starttimingEntrystartTime属性値とする。

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

  4. nametimingEntryname属性値とする。

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

    1. eventCountswindoweventCountsとする。

    2. eventCountsname含むことを確認。

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

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

    1. firstInputEntrytimingEntryのコピーとする。

    2. firstInputEntryentryTypeに"first-input"を設定。

    3. firstInputEntryをキューする。

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

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

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

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

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

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

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

    3. selector を返す。

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

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

高精度タイマーをウェブプラットフォームに追加することは、セキュリティ上の懸念があるため望ましくありません。 イベントハンドラーのタイムスタンプは、performance.now()と同じ精度です。 processingStartprocessingEnd はこの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. 2019年11月21日. 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. Paint Timing. 2025年9月15日. 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/
[POINTEREVENTS]
Jacob Rossi; Matt Brubeck. Pointer Events. 2019年4月4日. REC. URL: https://www.w3.org/TR/pointerevents/
[POINTEREVENTS4]
Patrick Lauke; Robert Flack. Pointer Events. 2025年10月15日. WD. URL: https://www.w3.org/TR/pointerevents4/
[RFC2119]
S. Bradner. RFCにおける要件レベルを示すキーワード. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[TOUCH-EVENTS]
Doug Schepers; 他. Touch Events. 2013年10月10日. REC. URL: https://www.w3.org/TR/touch-events/
[UIEVENTS]
Gary Kacmarcik; Travis Leithead. UI Events. 2024年9月7日. 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?