イベントタイミングAPI

W3C作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-event-timing-20260319/
最新版:
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 が以下のいずれかの場合: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は、物理的なユーザー入力発生時点(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である。
  • pointerdownpointerup、 または click であり、 タップまたはドラッグジェスチャーに属する。なお、 pointerdown が スクロールで終了する場合は除外される。

  • keydown または keyup はユーザーのキー押下に属する。

2.2. EventCounts インターフェイス

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

EventCounts オブジェクトは、キーがイベントの type 、値がその type の 発火したイベント数となるマップである。 このマップでカウントされるのは、 typePerformanceEventTiming エントリ(§ 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 を返す。

    注記: keydown および pointerdownfinalize event timing で “pending” としてマークされ、 後で interactionId の算出 時に更新される( keyuppointerup 等)。

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

  5. pendingKeyDownswindowpending key downs とする。

  6. pointerMapwindowpointer interaction value map とする。

  7. pendingPointerDownswindowpending pointer downs とする。

  8. typekeyup である場合:

    1. もし eventisComposing 属性値が true であれば、0 を返す。

    2. codeeventkeyCode 属性値とする。

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

    4. entrypendingKeyDowns[code] とする。

    5. interaction count を増加させる (window に対して)。

    6. interactionIdwindowuser interaction value とする。

    7. entryinteractionIdinteractionId に設定する。

    8. entrywindowentries to be queued に追加する。

    9. Remove pendingKeyDowns[code]。

    10. interactionId を返す。

  9. typecompositionstart である場合:

    1. pendingKeyDownsvalues の各 entry について:

      1. entrywindowentries to be queued に追加する。

    2. pendingKeyDowns をクリアする。

    3. 0 を返す。

  10. typeinput である場合:

    1. eventInputEvent のインスタンスでなければ、0 を返す。 注: このチェックは、 Events のうち typeinput であっても、修正されたテキスト内容に関係しない場合を除外するため。

    2. eventisComposing 属性値が false であれば、0 を返す。

    3. interaction count を増加させる (window に対して)。

    4. windowuser interaction value を返す。

  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 であれば、windowuser interaction value を返す。

      2. typepointerup かつ windowis contextmenu triggered フラグが true であれば:

        1. windowis contextmenu triggered フラグを false に設定する。

        2. windowuser interaction value を返す。

      3. その他の場合、0 を返す。

    5. pointerDownEntrypendingPointerDowns[pointerId] とする。

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

    7. typepointerup、 または contextmenu である場合:

      1. interaction count を増加させる (window に対して)。

      2. pointerMap[pointerId] を windowuser interaction value に設定する。

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

    8. pointerDownEntrywindowentries to be queued に追加する。

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

    10. typecontextmenu であれば、windowis contextmenu triggered を true に設定する。

    11. typepointercancel であれば、0 を返す。

    12. pointerMap[pointerId] を返す。

注記: このアルゴリズムは、イベントを対応する interaction ID に割り当てようとしています。 キーボードイベントでは、keydown が新しい interaction ID を生成し、keyup は以前の keydown に紐付ける必要があります。 ポインターイベントでは、pointerdown 時点では pointercancel または pointerup が発生するまでその interactionId を知ることはできません。 click は、前の pointerdown からの interaction ID とマッチさせようとします。 pointercancel または pointerup が発生した場合、interactionId を、保存されていた pointerdown に対応するエントリに設定する準備が整います。 pointercancel であれば、pointerdown に新しい interaction ID を割り当てないことを意味します。 pointerup であれば、新しい interaction 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. relevantGlobalis 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. relevantGlobalユーザー操作値 をユーザーエージェントが選択した小さな値だけ増加させる。

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

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

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

    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標準. Living Standard. 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; et al. HTML標準. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra標準. Living Standard. URL: https://infra.spec.whatwg.org/
[PAINT-TIMING]
Ian Clelland; Noam Rosenthal. Paint Timing. 2026年1月7日. WD. URL: https://www.w3.org/TR/paint-timing/
[PERFORMANCE-TIMELINE-2]
Nicolas Pena Moreno. Performance Timeline. 2025年5月21日. CRD. URL: https://www.w3.org/TR/performance-timeline/
[POINTEREVENTS4]
Patrick Lauke; Robert Flack. Pointer Events. 2026年2月25日. 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; et al. Touch Events. 2013年10月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標準. Living Standard. 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?