長いアニメーションフレーム API

W3C 第一公開作業草案,

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-long-animation-frames-20260428/
最新公開バージョン:
https://www.w3.org/TR/long-animation-frames/
編集者草案:
https://w3c.github.io/long-animation-frames/
履歴:
https://www.w3.org/standards/history/long-animation-frames/
テストスイート:
https://wpt.fyi/results/long-animation-frames
フィードバック:
GitHub
仕様内インライン
編集者:
(Google)

概要

この文書は、Web ページの作者が「長いアニメーションフレーム」の存在を検出するために使用できる API を定義する。 これは UI スレッドを長時間独占し、他の重要なタスク(たとえばユーザー入力への反応)の実行を妨げる。

この文書の状態

この節は、公開時点におけるこの文書の状態を説明する。 現在の W3C 公開文書の一覧 およびこの技術報告の最新リビジョンは W3C 標準および草案の索引で確認できる。

この文書は、 Web Performance Working Group により 勧告 トラックを用いた 第一公開作業草案として公開された。 第一公開作業草案としての公開は、 W3C およびそのメンバーによる承認を意味しない。

これは草案文書であり、 いつでも他の文書により更新、置換、 または廃止される可能性がある。 この文書を作業中のもの以外として引用することは適切ではない。

GitHub Issues が、この仕様に関する議論の 推奨される方法である。

この文書は、 2025年8月18日付 W3C Process Document に準拠する。

この文書は、 W3C Patent Policy の下で運営されるグループにより作成された。 W3C は、そのグループの成果物に関連して行われた特許開示の 公開リスト を維持している。 そのページには、特許を開示するための手順も含まれている。 個人が、その個人が Essential Claim(s) を含むと考える特許について実際の知識を有する場合、 W3C Patent Policy の第 6 節 に従ってその情報を開示しなければならない。

この文書に関するコメントを行う場合は、Long Animation Frames リポジトリに issue を作成してください。

1. はじめに

ページの読み込み中、およびその後にユーザーがページとやり取りしている間、アプリケーションと ブラウザーの両方がさまざまなイベントをキューに入れ、それらはその後ブラウザーによって実行される。たとえば、ユーザーエージェントは ユーザーの活動に基づいて入力イベントをスケジュールし、アプリケーションは requestAnimationFrame やその他のコールバックの コールバックをスケジュールする、などである。キューに入ると、ブラウザーはこれらのイベントを 1 つずつキューから取り出して実行する。

しかし、一部のタスクは長時間(複数フレーム)かかることがあり、その場合、UI スレッドが ブロックされ、他のすべてのタスクもブロックされる可能性がある。ユーザーには、これは一般に、ブラウザーがユーザー入力に 応答できない「ロックアップした」ページとして見える。これは今日の Web における悪いユーザー体験の大きな原因である:

遅延した「インタラクティブまでの時間」:

ページの読み込み中、あるいは完全に視覚的にレンダリングされた後であっても、長いタスクはしばしばメイン スレッドを占有し、ユーザーがページとやり取りすることを妨げる。設計の悪いサードパーティコンテンツが しばしば原因となる。

高い/変動する入力レイテンシ:

重要なユーザー操作イベント(例: tap、click、scroll、wheel など)は長いタスクの後ろにキューされ、 ぎこちなく予測できないユーザー体験をもたらす。

高い/変動するイベント処理レイテンシ:

入力と同様に、イベントコールバック(例: onload イベントなど)の処理はアプリケーションの更新を遅延させる。

ぎこちないアニメーションとスクロール:

一部のアニメーションおよびスクロール操作には、コンポジターとメインスレッド間の協調が必要である。 長いタスクがメインスレッドをブロックしている場合、アニメーションとスクロールの応答性に影響を与える可能性がある。

一部のアプリケーション(および RUM ベンダー)は、 「長いタスク」が発生する場合を特定し追跡しようとすでに試みている。たとえば、既知のパターンの 1 つは、 短い周期タイマーを設置し、連続する発火間の経過時間を調べることである。経過時間が タイマー周期より大きい場合、1 つ以上の長いタスクがイベントループの実行を遅延させた可能性が高い。 この方法はおおむね機能するが、いくつかの悪いパフォーマンス上の影響がある。長いタスクを検出するためにポーリングすることで、 アプリケーションは静止状態と長いアイドルブロックを妨げる(requestIdleCallback を参照)。バッテリー寿命に悪影響を及ぼす。 遅延の原因が何であるか(例: ファーストパーティコードかサードパーティコードか)を知る方法がない。

RAIL パフォーマンスモデルは、 アプリケーションはユーザー入力に 100ms 未満で応答すべきであると示唆している(タッチ移動とスクロールでは、 しきい値は 16ms である)。この API の目的は、アプリケーションがこれらの目標を達成するのを妨げる可能性のある タスクについて通知を表面化することである。この API は 50ms 以上かかるタスクを表面化する。これらのタスクがない Web サイトは、 ユーザー入力に 100ms 未満で応答できるはずである。ユーザー入力を受け取った時点で実行中のタスクを完了するのに 50ms 未満、そのようなユーザー入力に反応するタスクを実行するのに 50ms 未満で済むからである。

1.1. 使用例

const observer = new PerformanceObserver(function(list) {
    for (const entry of list.getEntries()) {
        // 長いタスク通知を処理する:
        // 分析と監視のために報告する
        // ...
    }
});
// 過去および将来の長いタスク通知のためにオブザーバーを登録する。
observer.observe({type: "long-animation-frame", buffered: true});
// この後の長いスクリプト実行により、オブザーバー内で
// "long-animation-frame" エントリがキューされ、受信される。

// 過去および将来の長いアニメーションフレーム通知のためにオブザーバーを登録する。
// この後、メインスレッドがビジーである長い期間により、オブザーバー内で
// "long-animation-frame" エントリがキューされ、受信される。
observer.observe({type: "long-animation-frame", buffered: true});

1.2. 長いアニメーションフレームと長いタスク

long tasks と長いアニメーションフレームはいずれも混雑とジャンクを測定するが、長い アニメーションフレームは、 ユーザーがこの種の混雑をどのように知覚するかとよりよく相関する情報を提供する。 これは、長いアニメーションフレームが、メインスレッドがアイドルになったときに始まり、 フレームがレンダリングされるか、またはユーザーエージェントがレンダリングするものはないと判断したときに終わるシーケンスを測定するためである。

task という用語は実装詳細のようなものであり、長いアニメーション フレームの追加は、 メインスレッドの混雑/ジャンクという同じ現象について、よりユーザー中心の指標を導入することによってそれを改善しようとする。

長いアニメーションフレームはレンダリングフェーズが最大 1 つであることが保証されるため、 レンダリングフェーズ自体に関する追加情報、たとえば renderStart や styleAndLayoutStart も公開できる。

2. 長いアニメーションフレームのタイミング

long animation frame は、継続時間が 50ms を超える次のいずれかの発生を指す:

Long Animation Frame timing には、次の新しいインターフェイスが含まれる:

2.1. PerformanceLongAnimationFrameTiming インターフェイス

[Exposed=Window]
interface PerformanceLongAnimationFrameTiming : PerformanceEntry {
    /* PerformanceEntry のオーバーロード */
    readonly attribute DOMHighResTimeStamp startTime;
    readonly attribute DOMHighResTimeStamp duration;
    readonly attribute DOMString name;
    readonly attribute DOMString entryType;

    readonly attribute DOMHighResTimeStamp renderStart;
    readonly attribute DOMHighResTimeStamp styleAndLayoutStart;
    readonly attribute DOMHighResTimeStamp blockingDuration;
    readonly attribute DOMHighResTimeStamp firstUIEventTimestamp;
    [SameObject] readonly attribute FrozenArray<PerformanceScriptTiming> scripts;
    [Default] object toJSON();
};

PerformanceLongAnimationFrameTiming includes PaintTimingMixin;

PerformanceLongAnimationFrameTiming は frame timing info timing info を持つ。

entryType 属性の getter 手順は、"long-animation-frame" を返すことである。

name 属性の getter 手順は、"long-animation-frame" を返すことである。

startTime 属性の getter 手順は、relative high resolution time を返すことである。これは this の timing info の start time と this の relevant global object が与えられたものである。

duration 属性の getter 手順は、duration を返すことである。これは this の startTime と、relative high resolution time との間のものである。後者は this の timing info の end time と this の relevant global object が与えられたものである。

renderStart 属性の getter 手順は、relative high resolution time を返すことである。これは this の timing info の update the rendering start time と this の relevant global object が与えられたものである。

styleAndLayoutStart 属性の getter 手順は、relative high resolution time を返すことである。これは this の timing info の style and layout start time と this の relevant global object が与えられたものである。

firstUIEventTimestamp 属性の getter 手順は、relative high resolution time を返すことである。これは this の timing info の first ui event timestamp と this の relevant global object が与えられたものである。

blockingDuration 属性の getter 手順は次のとおりである:

  1. sortedTaskDurations を timing info の task durations を 降順にソートしたものとする。

  2. this の timing info の update the rendering start time が 0 でない場合、次を実行する:

    1. renderDuration を、duration とする。これは this の renderStart と relative high resolution time との間のものであり、後者は this の timing info の end time が与えられたものである。

    2. sortedTaskDurations[0] を renderDuration だけ増加させる。

      注: これにより、最長の task duration + render duration は、その合計 duration が >50ms であれば blocking とみなされる。

  3. totalBlockingDuration を 0 とする。

  4. sortedTaskDurations 内の各 duration について 反復し、 duration が 50 より大きい場合、totalBlockingDuration を duration - 50 だけ増加させる。

  5. totalBlockingDuration を返す。

scripts 属性の getter 手順は次のとおりである:

  1. scripts を list « » とする。

  2. entryWindow を this の relevant global object とする。

  3. For each scriptInfo in this の frame timing info の scripts:

    1. scriptWindow を scriptInfo の window とする。

    2. scriptEntry を、this の relevant realm 内の新しい PerformanceScriptTiming とする。 その timing info は scriptInfo であり、その window attribution は 最初に一致する文に対応する値である:

      scriptWindow is undefined

      other

      scriptWindow is entryWindow

      self

      entryWindow の関連 Document の node navigable の ancestor navigables が、scriptWindow の関連 Document の node navigable を contains する

      ancestor

      scriptWindow の関連 Document の node navigable の ancestor navigables が、entryWindow の関連 Document の node navigable を contains する

      descendant

      entryWindow の関連 Document の node navigable の top-level traversable が、scriptWindow の 関連 Document の node navigable の top-level traversable である

      same-page

      Otherwise

      other.

    3. scriptEntry を scripts に append する。

  4. scripts を返す。

2.2. PerformanceScriptTiming インターフェイス

enum ScriptInvokerType {
    "classic-script",
    "module-script",
    "event-listener",
    "user-callback",
    "resolve-promise",
    "reject-promise"
};

enum ScriptWindowAttribution {
    "self", "descendant", "ancestor", "same-page", "other"
};

[Exposed=Window]
interface PerformanceScriptTiming : PerformanceEntry {
    /* PerformanceEntry のオーバーロード */
    readonly attribute DOMHighResTimeStamp startTime;
    readonly attribute DOMHighResTimeStamp duration;
    readonly attribute DOMString name;
    readonly attribute DOMString entryType;

    readonly attribute ScriptInvokerType invokerType;
    readonly attribute DOMString invoker;
    readonly attribute DOMHighResTimeStamp executionStart;
    readonly attribute DOMString sourceURL;
    readonly attribute DOMString sourceFunctionName;
    readonly attribute long long sourceCharPosition;
    readonly attribute DOMHighResTimeStamp pauseDuration;
    readonly attribute DOMHighResTimeStamp forcedStyleAndLayoutDuration;
    readonly attribute Window? window;
    readonly attribute ScriptWindowAttribution windowAttribution;
    [Default] object toJSON();
};

PerformanceScriptTiming は、関連する script timing info timing info を持つ。

PerformanceScriptTiming は、関連する ScriptWindowAttribution window attribution を持つ。

entryType 属性の getter 手順は、"script" を返すことである。

name 属性の getter 手順は、"script" を返すことである。

invokerType 属性の getter 手順は、this の timing info の invoker type を返すことである。

invoker 属性の getter 手順は次のとおりである:

  1. this の invokerType に応じて分岐する:

    "`classic-script`"
    "`module-script`"

    this の timing info の source url を返す。

    "`event-listener`"
    1. targetName を this の timing info の invoker name とする。

    2. this の timing info の event target element id が空文字列でない場合: targetName を « targetName, "#", this の timing info の event target element id » の concatenation に設定する。

    3. そうでなく、this の timing info の event target element src attribute が空文字列でない場合: targetName を « targetName, "[src=", this の timing info の event target element src attribute, "]" » の concatenation に設定する。

    4. « targetName, ".on", this の timing info の event type » の concatenation を返す。

    これは 少し独自仕様に感じられるため、名前生成について議論する必要がある。

    "`user-callback`"

    this の timing info の invoker name を返す。

    "`resolve-promise`"
    "`reject-promise`"
    1. this の timing info の invoker name が空文字列である場合、 次を実行する:

      1. this の invokerType が "`resolve-promise`" であれば、"`Promise.resolve`" を返す。

      2. そうでなければ、"`Promise.reject`" を返す。

    2. invokerType が "`resolve-promise`" であれば thenOrCatch を "`then`" とし、そうでなければ "`reject-promise`" とする。

    3. « invoker name, ".", thenOrCatch » の concatenation を返す。

startTime 属性の getter 手順は、relative high resolution time を返すことである。これは this の timing info の start time と this の relevant global object が与えられたものである。

duration 属性の getter 手順は、duration を返すことである。これは this の startTime と、relative high resolution time との間のものである。後者は this の timing info の end time と this の relevant global object が与えられたものである。

executionStart 属性の getter 手順は、this の timing info の execution start time が 0 であれば 0 を返し、そうでなければ relative high resolution time を返すことである。これは this の timing info の execution start time と this の relevant global object が与えられたものである。

forcedStyleAndLayoutDuration 属性の getter 手順は、スタイルとレイアウトを同期的に実行するために費やされた時間を表す implementation-defined な値を返すことである。たとえば getComputedStyle() や getBoundingClientRect() の呼び出しによるものである。

これを 相互運用可能/規範的にする方法を見つける。おそらく WebIDL でこれらの関数を同期スタイル/レイアウトを必要とするものとしてマークするか? それが解決したら timing info に移す。

pauseDuration 属性の getter 手順は、this の timing info の pause duration を返すことである。

sourceURL 属性の getter 手順は、this の timing info の source url を返すことである。 sourceFunctionName 属性の getter 手順は、this の timing info の source function name を返すことである。 sourceCharPosition 属性の getter 手順は、this の timing info の source character position を返すことである。

window 属性の getter 手順は次のとおりである:

  1. window を、deref を this の timing info の window に対して呼び出した結果とする。

  2. window が undefined であれば null を返し、そうでなければ window を返す。

windowAttribution 属性の getter 手順は、this の window attribution を返すことである。

3. 処理モデル

注: Long Animation Frame API を実装するユーザーエージェントは、それぞれ "long-animation-frame" を supportedEntryTypes に、Window コンテキスト用に含める必要がある。

3.1. フレームタイミング情報

frame timing info は、 長いアニメーションフレームのアルゴリズムによって帳簿管理の詳細として使用される struct である。 これは次の items を持つ:
start time
current task start time
update the rendering start time
style and layout start time
first ui event timestamp
end time

DOMHighResTimeStamp。 初期値は 0。 注: 上記はすべて unsafe であり、 API を介して公開されるときには coarsened されるべきである。

task durations

DOMHighResTimeStamp の list。 初期値は空である。

scripts

script timing info の list。 初期値は空である。

pending script

Null または script timing info。初期値は null である。

script timing info は struct である。これは 次の items を持つ:

invoker type

ScriptInvokerType。

start time
end time
execution start time

unsafe な DOMHighResTimeStamp。 初期値は 0。

pause duration

ミリ秒数を表す DOMHighResTimeStamp。 初期値は 0。

invoker name
source url
source function name
event type
event target element id
event target element src attribute

文字列。初期値は空文字列である。

source character position

数値。初期値は -1。

window

WeakRef。 Window への参照である。

Document は、null または frame timing info である current frame timing info を持つ。初期値は null である。

3.2. 長いアニメーションフレームを報告する

3.2.1. 長いアニメーションフレームの監視 {#loaf-monitoring}

Document document について nearest same-origin root を取得するには:
  1. ancestors を document の ancestor navigables とする。

  2. ancestors 内の各 ancestorNavigable について 反復する: ancestorNavigable の active document の origin が document の origin と same origin であり、 かつ ancestorNavigable の active document の relevant agent が document の relevant agent である場合、 ancestorNavigable の active document を返す。

  3. document を返す。

Document document の relevant frame timing info は、その nearest same-origin root の current frame timing info である。

DOMHighResTimeStamp unsafeTaskStartTime と Document document が与えられたときに、record task start time するには:
  1. root を document の nearest same-origin root とする。

  2. root の current frame timing info が null である場合、 root の current frame timing info を新しい frame timing info に設定する。その start time は unsafeTaskStartTime である。

  3. root の current frame timing info の current task start time を unsafeTaskStartTime に設定する。

  4. root の current frame timing info の 's start time が 0 の場合、root の current frame timing info の start time を unsafeTaskStartTime に設定する。

DOMHighResTimeStamp unsafeTaskEndTime と Document document が与えられたときに、record task end time するには:
  1. timingInfo を document の relevant frame timing info とする。

  2. timingInfo が null の場合、return する。

    注: これは、シーケンス中にブラウザーが hidden になった場合に発生しうる。

  3. safeTaskEndTime を、unsafeTaskEndTime と document の relevant global object が与えられた relative high resolution time とする。

  4. safeTaskStartTime を、timingInfo の current task start time と document の relevant global object が与えられた relative high resolution time とする。

  5. safeTaskStartTime と safeTaskEndTime の間の duration を timingInfo の task durations に append する。

  6. ユーザーエージェントが、document の node navigable のレンダリングを更新しても可視効果がないと考える場合:

    1. document の nearest same-origin root の current frame timing info を null に設定する。

    2. frameDuration を、timingInfo の start time と global が与えられた relative high resolution time と、unsafeTaskEndTime と global が与えられた relative high resolution time との間の duration とする。

    3. frameDuration が 50 ミリ秒以上である場合、document、timingInfo、および新しい [/=paint timing info=] が与えられた queue a long animation frame entry を実行する。

    注: 実際の視覚的更新がなかったとしても、 ここで long animation frame としてマークする。これは、無関係な視覚的更新と一致したシナリオでは blocking になるためである。

Document document と DOMHighResTimeStamp unsafeStyleAndLayoutStart が与えられたときに、record rendering time するには:
  1. timingInfo を document の relevant frame timing info とする。

  2. timingInfo が null の場合、return する。

    注: これは、シーケンス中にブラウザーが hidden になった場合に発生しうる。

  3. frameDuration を、timingInfo の start time と global が与えられた relative high resolution time と、 global が与えられた current high resolution time との間の duration とする。

  4. frameDuration が 50 ミリ秒未満である場合、document の nearest same-origin root の current frame timing info を null に設定し、return する。

  5. timingInfo の update the rendering start time を timingInfo の current task start time に設定する。

  6. timingInfo の style and layout start time を unsafeStyleAndLayoutStart に設定する。

Document document、frame timing info timingInfo、および paint timing info paintTimingInfo が与えられたときに、queue a long animation frame entry するには、 document の relevant realm 内の新しい PerformanceLongAnimationFrameTiming を queue する。 その timing info は timingInfo であり、その paint timing info は paintTimingInfo である。

3.2.2. 長いスクリプトの監視

callback function callback と environment settings object settings が与えられたときに、 record timing info for user callback するには: settings、"`user-callback`"、および script timing info scriptTimingInfo が与えられた次の手順を用いて、Create script entry point を実行する:
  1. scriptTimingInfo の invoker name を callback の identifier に設定する。

  2. callback が与えられた scriptTimingInfo に対して Apply source location を実行する。

文字列または Function handler、environment settings object settings、および boolean repeat が与えられたときに、record timing info for timer handler するには: settings、"`user-callback`"、 および script timing info scriptTimingInfo が与えられた次の手順を用いて、 Create script entry point を実行する:
  1. repeat が true であれば setTimeoutOrInterval を "setInterval" とし、 そうでなければ "setTimeout" とする。

  2. scriptTimingInfo の invoker name を « TimerHandler:", setTimeoutOrInterval » の concatenation に設定する。

  3. handler が Function であれば、handler が与えられた scriptTimingInfo に対して apply source location を実行する。

Event event と EventListener listener が与えられたときに、record timing info for event listener するには: listener の relevant settings object、"`event-listener`"、 および script timing info scriptTimingInfo と frame timing info frameTimingInfo が与えられた次の手順を用いて、Create script entry point を実行する:
  1. scriptTimingInfo の event type を event の type に設定する。

  2. target を event の currentTarget とする。

  3. target が Node であれば、次を実行する:

    1. scriptTimingInfo の invoker name を target の nodeName に設定する。

    2. target が Element であれば、次を実行する:

      1. scriptTimingInfo の event target element id を target の id に設定する。

      2. scriptTimingInfo の event target element src attribute を、target と "`src`" について getting an attribute value by name した結果に設定する。

  4. そうでなければ、scriptTimingInfo の invoker name を target の interface name に設定する。

  5. listener の callback が与えられた scriptTimingInfo に対して Apply source location を実行する。

  6. event が UIEvent であり、 かつ frameTimingInfo の first ui event timestamp が 0 の場合、 frameTimingInfo の first ui event timestamp を event の timeStamp に設定する。

Promise promise と "`resolve-promise`" または "`reject-promise`" の type が与えられたときに、 record timing info for promise resolver するには:
  1. promise の relevant realm の settings object、type、 および script timing info scriptTimingInfo が与えられた次の手順を用いて Create script entry point を実行する:

    1. scriptTimingInfo の invoker name を promise の invoker name when created に設定する。

    2. scriptTimingInfo の source url を promise の script url when created に設定する。

script timing info scriptTimingInfo、script script、および URL-or-null url が与えられたときに、 set source url for script block するには:
  1. url が null の場合、return する。

  2. url の scheme が "`http`" または "`https`" であれば、 scriptTimingInfo の source url を script の base URL に設定する。

  3. そうでなく、url の scheme が "`blob`" または "`data`" であれば、 scriptTimingInfo の source url を « url の scheme, ":"" » の concatenation に設定する。

script script と URL-or-null originalSourceURL が与えられたときに、record classic script creation time するには:
  1. script の settings object、"`classic-script`"、 および script timing info scriptTimingInfo が与えられた次の手順を用いて Create script entry point を実行する: scriptTimingInfo、script、および originalSourceURL が与えられた Set source url for script block を実行する。

classic script script が与えられたときに、 record classic script execution start time するには:
  1. settings を script の settings object とする。

  2. script の muted errors が true であれば、return する。

  3. settings が Window でなければ、return する。

  4. document を settings の document とする。

  5. frameTimingInfo を document の relevant frame timing info とする。

  6. frameTimingInfo が null、または frameTimingInfo の pending script が null でない場合、return する。

  7. Assert: frameTimingInfo の pending script の invoker type は "`classic-script`" である。

  8. frameTimingInfo の pending script の execution start time を unsafe shared current time に設定する。

module script script が与えられたときに、 record module script execution start time するには: script の settings object、"`module-script`"、 および script timing info scriptTimingInfo が与えられた次の手順を用いて Create script entry point を実行する:
  1. scriptTimingInfo の execution start time を script の scriptTimingInfo の start time に設定する。

  2. scriptTimingInfo、script、および script の base URL が与えられた Set source url for script block を実行する。

environment settings object settings、 ScriptInvokerType invokerType、および steps が与えられたときに、create script entry point するには。 ここで steps は、script timing info と任意の frame timing info を取るアルゴリズムである:
  1. settings が Window でなければ、return する。

  2. document を settings の document とする。

  3. document が fully active でない、または hidden である場合、return する。

  4. frameTimingInfo を document の relevant frame timing info とする。

  5. frameTimingInfo が null の場合、return する。

  6. frameTimingInfo の pending script が null でない場合、return する。

  7. scriptTimingInfo を新しい script timing info とする。 その start time は unsafe shared current time であり、 その invoker type は invokerType である。

  8. steps を scriptTimingInfo と frameTimingInfo が与えられたものとして実行する。

  9. scriptTimingInfo の window を settings に設定する。

  10. frameTimingInfo の pending script を scriptTimingInfo に設定する。

record timing info for microtask checkpoint するには:
  1. script を running script とする。

  2. settings を script の settings object とする。

  3. document を settings の document とする。

  4. document が fully active でない、または hidden である場合、return する。

  5. frameTimingInfo を document の relevant frame timing info とする。

  6. scriptTimingInfo を frameTimingInfo の pending script とする。

  7. frameTimingInfo の pending script を null に設定する。

  8. scriptTimingInfo が null の場合、return する。

  9. scriptTimingInfo の end time を unsafe shared current time に設定する。

  10. script が classic script であり、その muted errors が true である場合:

    1. scriptTimingInfo の source url を空文字列に設定する。

    2. scriptTimingInfo の source character position を -1 に設定する。

    3. scriptTimingInfo の source function name を 空文字列に設定する。

  11. scriptTimingInfo の start time と scriptTimingInfo の end time の間の duration が 5 ミリ秒より大きい場合、 scriptTimingInfo を frameTimingInfo の scripts に append する。

script timing info scriptTimingInfo と、callback function または Function callback が与えられたときに、scriptTimingInfo に apply source location するには:
  1. ユーザーエージェントは、scriptTimingInfo の source url を、callback が定義されたスクリプトのソース URL に設定してよい。

  2. ユーザーエージェントは、scriptTimingInfo の source function name を callback の関数名に設定してよい。

  3. ユーザーエージェントは、scriptTimingInfo の source character position を callback が定義された文字位置に設定してよい。

duration duration が与えられたときに、 record pause duration するには:
  1. script を running script とする。

  2. settings を script の settings object とする。

  3. settings が Window でなければ、return する。

  4. document を settings の document とする。

  5. document が fully active でない、または hidden である場合、return する。

  6. frameTimingInfo を document の relevant frame timing info とする。

  7. frameTimingInfo が null の場合、return する。

  8. frameTimingInfo の pending script が null の場合、return する。

  9. frameTimingInfo の pending script の pause duration を、 duration のミリ秒値だけ増加させる。

4. 既存の標準への追加

4.1. WebIDL 標準へのモンキーパッチ

Promise インターフェイスは、関連する文字列 invoker name when created を持つ。初期値は "`Promise`" である。 Promise インターフェイスは、関連する文字列 script url when created を持つ。初期値は空 文字列である。

creating a new promise に、Promise を返す前に、 次の手順を追加する:

  1. interfaceName を、この promise の作成に責任を持つ interface を表す文字列とする。

  2. attributeName を、この promise の作成に責任を持つ interface 内の attribute を表す文字列とする。

  3. 作成された Promise の script url when created を running script の base URL に設定する。

  4. ユーザーエージェントは、作成された Promise の invoker name when created を、 « interfaceName, ".", attributeName » の最後に知られた concatenation に設定してよい。

    これはかなり 曖昧である。規範的な方法で行うことが難しいためである。 これを改善できるか、あるいは promise ハンドラーの source location は多少 implementation-defined のままになるのかを確認する必要がある。

Promise p が与えられた resolve a promise に、次の手順を前置する: p と "`resolve-promise`" が与えられた Record timing info for promise resolver を実行する。

Promise p が与えられた reject a promise に、 次の手順を前置する: p と "`reject-promise`" が与えられた Record timing info for promise resolver を実行する。

invoke a callback function に、environment settings object relevant settings と callback function F を得た時点で、 次の手順を挿入する: F と relevant settings が与えられた Record timing info for user callback を実行する。

5. セキュリティおよびプライバシーの考慮事項

Long Animation Frames API は、長いタスクのソースに関する origin-safe attribution information を含めることで same-origin policy に従う。長いタスクには 50ms のしきい値がある。継続時間は 1 ms の粒度でのみ提供される。これらにより、クロスオリジン漏洩に対して十分な保護が提供される。

Long Animation Frames API は、ユーザーによって実行されたタスクの継続時間と種類に関するタイミング情報、 および関数呼び出しを引き起こした browsing context などの attribution を提供する。これにより、攻撃者が ユーザーの行動を推測したり、ユーザーを識別したりするためのサイドチャネルタイミング攻撃を実行できる可能性がある。 たとえば、長いスクリプトの後に長いレンダーが続くパターンを組み合わせて、ソーシャル ウィジェットに対するユーザーの操作を推測できる。詳細な関数呼び出し attribution は、ユーザーの行動を特定するために使用されうる。

5.1. オブザーバーには何が公開されるか?

トップレベルページ内のすべてのオブザーバー(すなわち、ページ内のすべての iframe とメインフレーム)は、 長いアニメーションフレームの存在に関する通知を受け取る。タスクの開始時刻、その継続時間 (1 ms の粒度)、および原因となるフレームへのポインターを公開する。この情報は現在でも、 setTimeout を用いて、より高い解像度で観測できる。攻撃者は、ページ上の他のものをすべて消去し、 脆弱なクロスオリジンリソースを追加して、setTimeout からの遅延がそのリソースにより引き起こされることを保証することで、 これを行える。他の異なるページ(タブまたはウィンドウ)のオブザーバーは、ユーザーエージェントの アーキテクチャに関係なく通知を受け取るべきではない。

5.2. 考慮された攻撃シナリオ

考慮されたタイミング攻撃は次のとおりである:

  1. 従来のタイミング攻撃: 外部リソースの読み込み時間を用いて、 private data のサイズを明らかにする。たとえば、ギャラリー内の隠し画像の数、ユーザー名が 有効かどうか、などである。例を参照。

  2. サイドチャネルタイミング攻撃: 動画解析、スクリプト解析、App Cache 読み取り、 または Cache API(service workers)の使用にかかる時間を用いて、ユーザーを一意に識別したり、 ユーザーの年齢、性別、場所、興味などのプロファイルを作成したりする。 たとえば、ソーシャルネットワークからの ステータス更新を特定の属性(例: 20〜30 歳の女性)に限定できる場合、パーマリンクページのファイルサイズを 用いて、ユーザーが対象属性に含まれるかどうかを判断できる。

これらのシナリオは、50ms しきい値とクロスオリジン境界の尊重、すなわち信頼されていないクロスオリジン オブザーバーにタスクの種類や追加の attribution を表示しないことによって対処される。

5.3. Long Animation Frames API によって公開される追加情報

複数のクロスオリジン文書が同じイベントループを共有できるため、それらは同じフレームシーケンスの一部として レンダリングされ、互いのレンダリング時間に影響を与えることもできる。これにより、これらのタイミングは すでにある程度クロスオリジンで観測可能である。たとえば、animation frame を要求し、それが遅延するかどうかを観測することである。 ただし、長いアニメーションフレームはそれらをより高い忠実度で公開する。

これを緩和するために、長いアニメーションフレームは「participating local roots」にのみ報告される。 シーケンスに寄与した作業タスクに関連付けられた文書、またはフレームの一部としてレンダリングされた文書のみが、 長いアニメーションフレームを観測する資格を持ち、その長いアニメーションフレームは、topmost であるか クロスオリジン親を持つ最も近い祖先においてのみ利用可能となる。

5.4. PerformanceScriptTiming と不透明なスクリプト

PerformanceScriptTiming はスクリプト実行に関する情報を公開するため、 それ以外では容易に推測できない CORS cross-origin スクリプトに関する情報を過剰に公開しないようにする必要がある。 そのために、既存の muted errors boolean を使用し、そのような場合には空の sourceURL を報告する。

適合性

文書の 表記規約

適合性要件は、記述的な表明と 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" によって分離される。 次のようになる:

注、これは参考情報としての注である。

適合する アルゴリズム

アルゴリズムの一部として命令形で表現された要件 (たとえば "strip any leading space characters" や "return false and abort these steps" など)は、 そのアルゴリズムを導入する際に使用されるキーワード ("must", "should", "may" など)の意味で解釈される。

アルゴリズムまたは特定の手順として表現された適合性要件は、 最終結果が等価である限り、 どのような方法でも実装できる。 とくに、この仕様で定義されるアルゴリズムは 理解しやすいことを意図しており、 高性能であることを意図していない。 実装者は最適化することが推奨される。

索引

この仕様によって定義される 用語

参照により定義される 用語

参考文献

規範的参考文献

[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021年8月26日. WD. URL: https://www.w3.org/TR/cssom-1/
[CSSOM-VIEW-1]
Simon Fraser; Emilio Cobos Álvarez. CSSOM View Module. 2025年9月16日. WD. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[HR-TIME-2]
Ilya Grigorik. High Resolution Time Level 2. 2019年11月21日. REC. URL: https://www.w3.org/TR/hr-time-2/
[HR-TIME-3]
Yoav Weiss. High Resolution Time. 2026年3月24日. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[LONGTASKS-1]
Noam Rosenthal. Long Tasks API. 2026年3月19日. WD. URL: https://www.w3.org/TR/longtasks-1/
[PAINT-TIMING]
Ian Clelland; Noam Rosenthal. Paint Timing. 2026年3月24日. WD. URL: https://www.w3.org/TR/paint-timing/
[PERFORMANCE-TIMELINE]
Nicolas Pena Moreno. Performance Timeline. 2025年5月21日. CRD. URL: https://www.w3.org/TR/performance-timeline/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[UIEVENTS]
Xiaoqian Wu. UI Events. 2026年2月21日. WD. URL: https://www.w3.org/TR/uievents/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

IDL 索引

[Exposed=Window]
interface PerformanceLongAnimationFrameTiming : PerformanceEntry {
    /* PerformanceEntry のオーバーロード */
    readonly attribute DOMHighResTimeStamp startTime;
    readonly attribute DOMHighResTimeStamp duration;
    readonly attribute DOMString name;
    readonly attribute DOMString entryType;

    readonly attribute DOMHighResTimeStamp renderStart;
    readonly attribute DOMHighResTimeStamp styleAndLayoutStart;
    readonly attribute DOMHighResTimeStamp blockingDuration;
    readonly attribute DOMHighResTimeStamp firstUIEventTimestamp;
    [SameObject] readonly attribute FrozenArray<PerformanceScriptTiming> scripts;
    [Default] object toJSON();
};

PerformanceLongAnimationFrameTiming includes PaintTimingMixin;

enum ScriptInvokerType {
    "classic-script",
    "module-script",
    "event-listener",
    "user-callback",
    "resolve-promise",
    "reject-promise"
};

enum ScriptWindowAttribution {
    "self", "descendant", "ancestor", "same-page", "other"
};

[Exposed=Window]
interface PerformanceScriptTiming : PerformanceEntry {
    /* PerformanceEntry のオーバーロード */
    readonly attribute DOMHighResTimeStamp startTime;
    readonly attribute DOMHighResTimeStamp duration;
    readonly attribute DOMString name;
    readonly attribute DOMString entryType;

    readonly attribute ScriptInvokerType invokerType;
    readonly attribute DOMString invoker;
    readonly attribute DOMHighResTimeStamp executionStart;
    readonly attribute DOMString sourceURL;
    readonly attribute DOMString sourceFunctionName;
    readonly attribute long long sourceCharPosition;
    readonly attribute DOMHighResTimeStamp pauseDuration;
    readonly attribute DOMHighResTimeStamp forcedStyleAndLayoutDuration;
    readonly attribute Window? window;
    readonly attribute ScriptWindowAttribution windowAttribution;
    [Default] object toJSON();
};

Issues 索引

これは少し独自仕様に感じられるため、名前生成について議論する必要がある。 ↵
これを相互運用可能/規範的にする方法を見つける。おそらく WebIDL でこれらの関数を 同期スタイル/レイアウトを必要とするものとしてマークするか? それが解決したら timing info に移す。 ↵
これはかなり曖昧である。規範的な方法で行うことが難しいためである。 これを改善できるか、あるいは promise ハンドラーの source location は多少 implementation-defined のままになるのかを確認する必要がある。 ↵