長いアニメーションフレーム 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 つであることが保証されるため、 レンダリングフェーズ自体に関する追加情報、たとえば renderStartstyleAndLayoutStart も公開できる。

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;

PerformanceLongAnimationFrameTimingframe timing info timing info を持つ。

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

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

startTime 属性の getter 手順は、relative high resolution time を返すことである。これは thistiming infostart timethisrelevant global object が与えられたものである。

duration 属性の getter 手順は、duration を返すことである。これは thisstartTime と、relative high resolution time との間のものである。後者は thistiming infoend timethisrelevant global object が与えられたものである。

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

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

firstUIEventTimestamp 属性の getter 手順は、relative high resolution time を返すことである。これは thistiming infofirst ui event timestampthisrelevant global object が与えられたものである。

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

  1. sortedTaskDurationstiming infotask durations降順にソートしたものとする。

  2. thistiming infoupdate the rendering start time が 0 でない場合、次を実行する:

    1. renderDuration を、duration とする。これは thisrenderStartrelative high resolution time との間のものであり、後者は thistiming infoend time が与えられたものである。

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

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

  3. totalBlockingDuration を 0 とする。

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

  5. totalBlockingDuration を返す。

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

  1. scriptslist « » とする。

  2. entryWindowthisrelevant global object とする。

  3. For each scriptInfo in thisframe timing infoscripts:

    1. scriptWindowscriptInfowindow とする。

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

      scriptWindow is undefined

      other

      scriptWindow is entryWindow

      self

      entryWindow の関連 Documentnode navigableancestor navigables が、scriptWindow の関連 Documentnode navigablecontains する

      ancestor

      scriptWindow の関連 Documentnode navigableancestor navigables が、entryWindow の関連 Documentnode navigablecontains する

      descendant

      entryWindow の関連 Documentnode navigabletop-level traversable が、scriptWindow の 関連 Documentnode navigabletop-level traversable である

      same-page

      Otherwise

      other.

    3. scriptEntryscriptsappend する。

  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 手順は、thistiming infoinvoker type を返すことである。

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

  1. thisinvokerType に応じて分岐する:

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

    thistiming infosource url を返す。

    "`event-listener`"
    1. targetNamethistiming infoinvoker name とする。

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

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

    4. « targetName, ".on", thistiming infoevent type » の concatenation を返す。

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

    "`user-callback`"

    thistiming infoinvoker name を返す。

    "`resolve-promise`"
    "`reject-promise`"
    1. thistiming infoinvoker name が空文字列である場合、 次を実行する:

      1. thisinvokerType が "`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 を返すことである。これは thistiming infostart timethisrelevant global object が与えられたものである。

duration 属性の getter 手順は、duration を返すことである。これは thisstartTime と、relative high resolution time との間のものである。後者は thistiming infoend timethisrelevant global object が与えられたものである。

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

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

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

pauseDuration 属性の getter 手順は、thistiming infopause duration を返すことである。

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

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

  1. window を、derefthistiming infowindow に対して呼び出した結果とする。

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

windowAttribution 属性の getter 手順は、thiswindow 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

DOMHighResTimeStamplist。 初期値は空である。

scripts

script timing infolist。 初期値は空である。

pending script

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

script timing infostruct である。これは 次の 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

WeakRefWindow への参照である。

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

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

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

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

  2. ancestors 内の各 ancestorNavigable について 反復する: ancestorNavigableactive documentorigindocumentoriginsame origin であり、 かつ ancestorNavigableactive documentrelevant agentdocumentrelevant agent である場合、 ancestorNavigableactive document を返す。

  3. document を返す。

Document documentrelevant frame timing info は、その nearest same-origin rootcurrent frame timing info である。

DOMHighResTimeStamp unsafeTaskStartTimeDocument document が与えられたときに、record task start time するには:
  1. rootdocumentnearest same-origin root とする。

  2. rootcurrent frame timing info が null である場合、 rootcurrent frame timing info を新しい frame timing info に設定する。その start timeunsafeTaskStartTime である。

  3. rootcurrent frame timing infocurrent task start timeunsafeTaskStartTime に設定する。

  4. rootcurrent frame timing info の 's start time が 0 の場合、rootcurrent frame timing infostart timeunsafeTaskStartTime に設定する。

DOMHighResTimeStamp unsafeTaskEndTimeDocument document が与えられたときに、record task end time するには:
  1. timingInfodocumentrelevant frame timing info とする。

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

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

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

  4. safeTaskStartTime を、timingInfocurrent task start timedocumentrelevant global object が与えられた relative high resolution time とする。

  5. safeTaskStartTimesafeTaskEndTime の間の durationtimingInfotask durationsappend する。

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

    1. documentnearest same-origin rootcurrent frame timing info を null に設定する。

    2. frameDuration を、timingInfostart timeglobal が与えられた relative high resolution time と、unsafeTaskEndTimeglobal が与えられた relative high resolution time との間の duration とする。

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

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

Document documentDOMHighResTimeStamp unsafeStyleAndLayoutStart が与えられたときに、record rendering time するには:
  1. timingInfodocumentrelevant frame timing info とする。

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

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

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

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

  5. timingInfoupdate the rendering start timetimingInfocurrent task start time に設定する。

  6. timingInfostyle and layout start timeunsafeStyleAndLayoutStart に設定する。

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

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

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

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

文字列または Function handlerenvironment 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. scriptTimingInfoinvoker name を « TimerHandler:", setTimeoutOrInterval » の concatenation に設定する。

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

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

  2. targeteventcurrentTarget とする。

  3. targetNode であれば、次を実行する:

    1. scriptTimingInfoinvoker nametargetnodeName に設定する。

    2. targetElement であれば、次を実行する:

      1. scriptTimingInfoevent target element idtargetid に設定する。

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

  4. そうでなければ、scriptTimingInfoinvoker nametarget の interface name に設定する。

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

  6. eventUIEvent であり、 かつ frameTimingInfofirst ui event timestamp が 0 の場合、 frameTimingInfofirst ui event timestampeventtimeStamp に設定する。

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

    1. scriptTimingInfoinvoker namepromiseinvoker name when created に設定する。

    2. scriptTimingInfosource urlpromisescript url when created に設定する。

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

  2. urlscheme が "`http`" または "`https`" であれば、 scriptTimingInfosource urlscriptbase URL に設定する。

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

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

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

  2. scriptmuted errors が true であれば、return する。

  3. settingsWindow でなければ、return する。

  4. documentsettingsdocument とする。

  5. frameTimingInfodocumentrelevant frame timing info とする。

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

  7. Assert: frameTimingInfopending scriptinvoker type は "`classic-script`" である。

  8. frameTimingInfopending scriptexecution start timeunsafe shared current time に設定する。

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

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

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

  2. documentsettingsdocument とする。

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

  4. frameTimingInfodocumentrelevant frame timing info とする。

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

  6. frameTimingInfopending script が null でない場合、return する。

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

  8. stepsscriptTimingInfoframeTimingInfo が与えられたものとして実行する。

  9. scriptTimingInfowindowsettings に設定する。

  10. frameTimingInfopending scriptscriptTimingInfo に設定する。

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

  2. settingsscriptsettings object とする。

  3. documentsettingsdocument とする。

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

  5. frameTimingInfodocumentrelevant frame timing info とする。

  6. scriptTimingInfoframeTimingInfopending script とする。

  7. frameTimingInfopending script を null に設定する。

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

  9. scriptTimingInfoend timeunsafe shared current time に設定する。

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

    1. scriptTimingInfosource url を空文字列に設定する。

    2. scriptTimingInfosource character position を -1 に設定する。

    3. scriptTimingInfosource function name を 空文字列に設定する。

  11. scriptTimingInfostart timescriptTimingInfoend time の間の duration が 5 ミリ秒より大きい場合、 scriptTimingInfoframeTimingInfoscriptsappend する。

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

  2. ユーザーエージェントは、scriptTimingInfosource function namecallback の関数名に設定してよい。

  3. ユーザーエージェントは、scriptTimingInfosource character positioncallback が定義された文字位置に設定してよい。

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

  2. settingsscriptsettings object とする。

  3. settingsWindow でなければ、return する。

  4. documentsettingsdocument とする。

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

  6. frameTimingInfodocumentrelevant frame timing info とする。

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

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

  9. frameTimingInfopending scriptpause 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. 作成された Promisescript url when createdrunning scriptbase URL に設定する。

  4. ユーザーエージェントは、作成された Promiseinvoker 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 settingscallback function F を得た時点で、 次の手順を挿入する: Frelevant 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 のままになるのかを確認する必要がある。