1. 序論
◎非規範的~web~appの処理能~特性を正確aに測定することは、 ~web~appを より速くするための重要な側面である。 この仕様は、 ~web開発者が, ~web~appの全存続期間にわたる様々な処理能~計量[ に~accessする / を計測する / を検索取得する ]ことを可能化するために必要yな`処理能~時列線$の~primitiveを定義する。 ◎ Accurately measuring performance characteristics of web applications is an important aspect of making web applications faster. This specification defines the necessary Performance Timeline primitives that enable web developers to access, instrument, and retrieve various performance metrics from the full lifecycle of a web application.
[ `NAVIGATION-TIMING-2$r は文書の~navi / `RESOURCE-TIMING-2$r は~page上の資源 / `USER-TIMING-2$r は開発者~script ]に関係する計時~情報を定義する仕様の例である。 これらは、 他の処理能~interfaceと伴に,~web~appの`処理能~時列線$を述べる処理能の計量を定義する。 例えば,次の~scriptは、 開発者が[ 文書の~navi / ~page上の資源 / 開発者~script ](同順)に関係する処理能~計量を得するために `処理能~時列線$に~accessする方法を示すものである: ◎ [NAVIGATION-TIMING-2], [RESOURCE-TIMING-2], and [USER-TIMING-2] are examples of specifications that define timing information related to the navigation of the document, resources on the page, and developer scripts, respectively. Together these and other performance interfaces define performance metrics that describe the Performance Timeline of a web application. For example, the following script shows how a developer can access the Performance Timeline to obtain performance metrics related to the navigation of the document, resources on the page, and developer scripts:
<!doctype html><html><head></head> <body onload="init()"> <img id="image0" src="https://www.w3.org/Icons/w3c_main.png" /> <script> function init() { /* `USER-TIMING-2$r を見よ ◎ see [[USER-TIMING-2]] */ performance.mark("startWork"); doWork(); /* 何らかの開発者~code ◎ Some developer code */ performance.mark("endWork"); measurePerf(); } function measurePerf() { performance .getEntries() .map(%entry => JSON.stringify(%entry, null, 2)) .forEach(%json => console.log(%json)); } </script> </body></html>
別法として,開発者は、 `処理能~時列線$を観測して,新たな処理能~計量が記録される度に `PerformanceObserver$I ~interfaceを介して通知させられる — 加えて,任意選択で、 指定した`~entry型$の,それまでに~bufferされた処理能~計量も通知させられる。 ◎ Alternatively, the developer can observe the Performance Timeline and be notified of new performance metrics and, optionally, previously buffered performance metrics of specified type, via the PerformanceObserver interface.
`PerformanceObserver$I ~interfaceは、 最初の例に示した~bufferに基づく~approachにおける制限に取組むように設計されている。 `PerformanceObserver$I ~interfaceを利用すれば、 ~appは: ◎ The PerformanceObserver interface was added and is designed to address limitations of the buffer-based approach shown in the first example. By using the PerformanceObserver interface, the application can:
- 時列線を調べ続ける( `polling^en )ことなく,新たな計量を検出できる。 ◎ Avoid polling the timeline to detect new metrics
- ~costがかかる~~重複排除~logic( `deduplication^en )なしに,新たな計量を識別できる。 ◎ Eliminate costly deduplication logic to identify new metrics
- ~bufferを操作しようと求める他の消費器との競争を排せる。 ◎ Eliminate race conditions with other consumers that may want to manipulate the buffer
開発者には、 アリな所では `PerformanceObserver$I を利用することが奨励される。 更には、 新たな処理能~APIの計量は, `PerformanceObserver$I ~interfaceを通す以外に可用にならないこともある。 観測器は、 構築子に~callbackを指定して,関心のある処理能~entryを `observe()$m ~methodを介して指定することにより働く。 ~callbackをいつ実行するかは、 ~UAが選ぶ — それは、 ~queueされた処理能~entryたちを受取る。 ◎ The developer is encouraged to use PerformanceObserver where possible. Further, new performance API's and metrics may only be available through the PerformanceObserver interface. The observer works by specifying a callback in the constructor and specifying the performance entries it's interested in via the observe() method. The user agent chooses when to execute the callback, which receives performance entries that have been queued.
`PerformanceObserver$I ~interfaceの利用に際し、 初期~page読込nに関する特別な考慮点がある: 登録が~eventを受取るためには,作動中でなければならないが、 登録~scriptは[ その時点で可用でないか, `critical path^en 内には欲されない ]こともあろう。 これに取組むため、 ~UAは,~pageが構築されている間 ある個数までの~eventを~bufferする — ~bufferされたこれらの~eventは、 観測器を登録するときに `buffered$d ~flagを介して~accessできる。 この~flagが ~T にされた場合、 ~UAは,指定された`~entry型$用に~bufferされた~eventを検索取得して配送し、 それらを `observe()$m ~callが生じた後の初回の~callbackに送達する。 ◎ There are special considerations regarding initial page load when using the PerformanceObserver interface: a registration must be active to receive events but the registration script may not be available or may not be desired in the critical path. To address this, user agents buffer some number of events while the page is being constructed, and these buffered events can be accessed via the buffered flag when registering the observer. When this flag is set, the user agent retrieves and dispatches events that it has buffered, for the specified entry type, and delivers them in the first callback after the observe() call occurs.
注記: ~bufferされる~eventの個数の上限は、 当の計量を定義する仕様により決定される。 ~buffer法は、 その上限個数までの~eventに限り利用されるものと意図され,継続的でもない。 ◎ Note The number of buffered events is determined by the specification that defines the metric and buffering is intended to used for first-N events only; buffering is not unbounded or continuous.
<!doctype html><html><head></head> <body> <img id="image0" src="https://www.w3.org/Icons/w3c_main.png" /> <script> /* 利用したい`~entry型$は~supportされているかどうかを知る関数 ◎ Know when the entry types we would like to use are not supported. */ function detectSupport(%entryTypes) { for (const %entryType of %entryTypes) { if (!PerformanceObserver.supportedEntryTypes.includes(%entryType)) { /* %entryType は~supportされていないことを~client側~解析に指示する。 ◎ Indicate to client-side analytics that entryType is not supported. */ } } } detectSupport(["resource", "mark", "measure"]); const %userTimingObserver = new PerformanceObserver(%list => { %list .getEntries() /* 挿入された値を取得する ◎ Get the values we are interested in */ .map(({ %name, %entryType, %startTime, %duration }) => { const %obj = { "Duration": %duration, "Entry Type": %entryType, "Name": %name, "Start Time": %startTime, }; return JSON.stringify(%obj, null, 2); }) /* それらを~consoleに表示する ◎ Display them to the console. */ .forEach(console.log); /* ~eventを処理したなら~disconnectする ◎ Disconnect after processing the events. */ %userTimingObserver.disconnect(); }); /* User-Timing 用に新たな~eventを申込む ◎ Subscribe to new events for User-Timing. */ %userTimingObserver.observe({entryTypes: ["mark", "measure"]}); const %resourceObserver = new PerformanceObserver(list => { list .getEntries() /* 関心ある値を取得する ◎ Get the values we are interested in */ .map(({ name, startTime, fetchStart, responseStart, responseEnd }) => { const %obj = { "Name": name, "Start Time": startTime, "Fetch Start": fetchStart, "Response Start": responseStart, "Response End": responseEnd, }; return JSON.stringify(%obj, null, 2); }) /* それらを~consoleに表示する ◎ Display them to the console. */ .forEach(console.log); /* ~eventを処理したなら~disconnectする ◎ Disconnect after processing the events. */ %resourceObserver.disconnect(); }); /* Resource Timing 用に~bufferされた~eventを検索取得するとともに,それ用に新たな~eventも申込む ◎ Retrieve buffered events and subscribe to newer events for Resource Timing. */ %resourceObserver.observe({type: "resource", buffered: true}); </script> </body> </html>
【この訳に特有な表記規約】
◎表記記号2. 適合性
【 この節の内容は ~W3C日本語訳 共通~page に移譲 】
3. 処理能~時列線
各 `大域~obj$は、 次に挙げるものを有する: ◎ Each global object has:
- `処理能~観測器~taskは~queue済みか@ ⇒ 真偽値 【初期~時は ~F 】 ◎ a performance observer task queued flag
-
`処理能~観測器~list@ ⇒ `処理能~観測器$たちが成す~list【実質的には`集合$】 — 初期~時は空とする。 ◎ a list of registered performance observer objects that is initially empty
`処理能~観測器$は、 この~list内にあることを `登録-済み@ であるともいう。
-
`処理能~entry~buffer~map@ ⇒ ある`~map$。 ◎ a performance entry buffer map map,\
この~mapを成す各`~entry$mapの: ◎ ↓
- `~key$mapは、 当の~bufferが所属する`~entry型$を表現する文字列を与える。 ◎ keyed on a DOMString, representing the entry type to which the buffer belongs.\
-
`値$mapは、 次に挙げるものからなる~tupleを与える: ◎ The map's value is the following tuple:
- `処理能~entry~buffer@ ⇒ `PerformanceEntry$I ~objたちを格納する。 初期~時は空とする。 ◎ A performance entry buffer to store PerformanceEntry objects, that is initially empty.
- `最大~buffer~size@ ⇒ 整数をとり,この`~entry型$用の`~registry$値に初期化される。 ◎ An integer maxBufferSize, initialized to the registry value for this entry type.
- `時列線から可用か@ ⇒ 真偽値をとり,この`~entry型$用の`~registry$値に初期化される。 ◎ A boolean availableFromTimeline, initialized to the registry value for this entry type.
- `落とした~entry数@ ⇒ 整数 — 初期~時は 0 とする。 ◎ An integer dropped entries count that is initially 0.
- `最後の処理能~entry~ID@ ⇒ 整数 — 初期~時は、 ~randomな整数 ~IN { 100 〜 10000 } に設定されるとする。 ◎ An integer last performance entry id that is initially set to a random integer between 100 and 10000.
各 `文書$は、 次に挙げるものを有する: ◎ Each Document has:
- `最も近過去な~navi@ ⇒ ある `PerformanceEntry$I — 初期~時は ε (未設定)とする。 ◎ A most recent navigation, which is a PerformanceEntry, initially unset.
`処理能~entry~tupleを得る@ ときは、 所与の ( %~entry型, %大域~obj ) に対し ⇒ ~RET %大域~obj の`処理能~entry~buffer~map$[ %~entry型 ] ◎ In order to get the relevant performance entry tuple, given entryType and globalObject as input, run the following steps: • Let map be the performance entry buffer map associated with globalObject. • Return the result of getting the value of an entry from map, given entryType as the key.
3.1. `Performance^I ~interfaceに対する拡張
この節では、 `HR-TIME-3$r の `Performance$I ~interfaceを拡張して,[ 処理能に関係する各種~属性, および[ `処理能~時列線$からの処理能~計量~dataを検索取得する ]ために利用される 各種~method ]を~hostするようにする。 ◎ This extends the Performance interface from [HR-TIME-3] and hosts performance related attributes and methods used to retrieve the performance metric data from the Performance Timeline.
partial interface `Performance$I { `PerformanceEntryList$I `getEntries$m(); `PerformanceEntryList$I `getEntriesByType$m(`DOMString$ %type); `PerformanceEntryList$I `getEntriesByName$m(`DOMString$ %name, optional `DOMString$ %type); }; typedef `sequence$<`PerformanceEntry$I> `PerformanceEntryList$I;
`PerformanceEntryList@I は、 `PerformanceEntry$I たちが成す連列を表現する — それは、 開発者に~JS配列~用の便利~methodすべてを供する。 ◎ The PerformanceEntryList represents a sequence of PerformanceEntry, providing developers with all the convenience methods found on JavaScript arrays.
【 この仕様の各所では、 `PerformanceEntry$I たちが成す`~list$は,暗黙的に `PerformanceEntryList$I ~objを成すものとして扱われる。 】
`getEntries()@m ~method手続きは ⇒ ~RET `~buffer~mapを名前と型で絞込む$( コレ, ~NULL, ~NULL )
◎ 3.1.1 getEntries() method ◎ Returns a PerformanceEntryList object returned by the filter buffer map by name and type algorithm with name and type set to null.`getEntriesByType(type)@m ~method手続きは ⇒ ~RET `~buffer~mapを名前と型で絞込む$( コレ, ~NULL, %type )
◎ 3.1.2 getEntriesByType() method ◎ Returns a PerformanceEntryList object returned by filter buffer map by name and type algorithm with name set to null, and type set to the method's input type parameter.`getEntriesByName(name, type)@m ~method手続きは:
- ~IF[ %type ~EQ ε ] ⇒ %type ~SET ~NULL
- ~RET `~buffer~mapを名前と型で絞込む$( コレ, %name, %type )
4. `PerformanceEntry^I ~interface
`PerformanceEntry$I ~interfaceは、 様々な計量による処理能~dataを~hostする。 ◎ The PerformanceEntry interface hosts the performance data of various metrics.
[`Exposed$=(Window,Worker)] interface `PerformanceEntry@I { readonly attribute `unsigned long long$ `id@m; readonly attribute `DOMString$ `name$m; readonly attribute `DOMString$ `entryType$m; readonly attribute `DOMHighResTimeStamp$I `startTime$m; readonly attribute `DOMHighResTimeStamp$I `duration$m; readonly attribute `unsigned long long$ `navigationId$m; [`Default$] `object$ `toJSON$m(); };
`name@m 取得子は ⇒ ~RET 初期化-時の値 ◎ name • This attribute must return the value it is initialized to.\
これは、 コレ用の識別子を表現する。 この識別子は、 一意になる必要はない。 ◎ It represents an identifier for this PerformanceEntry object. This identifier does not have to be unique.
`entryType@m 取得子~手続きは ⇒ ~RET 初期化-時の値 ◎ entryType • This attribute must return the value it is initialized to.
注記: `entryType$m 用の値は、 すべて,関連な`~registry$にて定義される。 例えば ⇒# `mark^l, `measure^l `USER-TIMING-2$r / `navigation^l `NAVIGATION-TIMING-2$r / `resource^l `RESOURCE-TIMING-2$r ◎ Note All entryType values are defined in the relevantregistry. Examples include: "mark" and "measure" [USER-TIMING-2], "navigation" [NAVIGATION-TIMING-2], and "resource" [RESOURCE-TIMING-2].
【 `entryType$m 用の値は, `~entry型@ とも称され、 通例的に, `PerformanceEntry$I を継承する各~interfaceごとに定義される。 `PerformanceEntry$I 自身は、 他から継承される基底~interfaceとして~serveする(~instance化されない)。 】
`startTime@m 取得子~手続きは ⇒ ~RET 初期化-時の値
これは、 コレの処理能~計量にて最初に記録された時刻~値を表現する。
◎ startTime • This attribute must return the value it is initialized to.\ It represents the time value of the first recorded timestamp of this performance metric.`duration@m 取得子~手続きは
- %終了~時刻 ~LET コレの`終了~時刻$pT
- ~IF[ %終了~時刻 ~EQ 0 ] ⇒ ~RET 0
- ~RET %終了~時刻 ~MINUS コレの `startTime$m
`toJSON()@m は、 `WebIDL$r の`既定の~toJSON手続き$に従うとする。 ◎ When toJSON is called, run [WebIDL]'s default toJSON steps.
各 `PerformanceEntry$I は `終了~時刻@pT を有する — それは `DOMHighResTimeStamp$I であり,初期~時は 0 とする。 ◎ A PerformanceEntry has a DOMHighResTimeStamp end time, initially 0.
`PerformanceEntry$I %~entry を `初期化する@PE ときは、 所与の ⇒# `DOMHighResTimeStamp$I %開始~時刻, 文字列 %~entry型, 文字列 %名前, `DOMHighResTimeStamp$I %終了~時刻 (省略時は 0 ) ◎終 に対し: ◎ To initialize a PerformanceEntry entry given a DOMHighResTimeStamp startTime, a DOMString entryType, a DOMString name, and an optional DOMHighResTimeStamp endTime (default 0):
- ~Assert: %~entry型 は`~registry$内に定義-済みである ◎ Assert: entryType is defined in the entry type registry.
- %~entry の ⇒# `startTime$m ~SET %開始~時刻, `entryType$m ~SET %~entry型, `name$m ~SET %名前, `終了~時刻$pT ~SET %終了~時刻 ◎ Initialize entry's startTime to startTime. ◎ Initialize entry's entryType to entryType. ◎ Initialize entry's name to name. ◎ Initialize entry's end time to endTime.
5. `PerformanceObserver^I ~interface
`PerformanceObserver$I ~interfaceを利用すれば、 `処理能~時列線$を観測して,新たな処理能~計量( `PerformanceEntry$I ~obj)が記録される度に通知させられる — 加えて、 任意選択で,~bufferされた処理能~計量も通知させられる。 ◎ The PerformanceObserver interface can be used to observe the Performance Timeline to be notified of new performance metrics as they are recorded, and optionally buffered performance metrics.
`PerformanceObserver$I ~objは、 単に `処理能~観測器@ とも称される。 各 `処理能~観測器$には、 次に挙げるものが結付けられる: ◎ Each PerformanceObserver has these associated concepts:
- `~callback@pO ⇒ 作成-時に設定される, `PerformanceObserverCallback$I ~callback。 ◎ A PerformanceObserverCallback observer callback set on creation.
- `~buffer@pO ⇒ `PerformanceEntryList$I ~obj。 この~objが表現する連列は、 初期~時は空とする。 ◎ A PerformanceEntryList object called the observer buffer that is initially empty.
- `種別@pO ⇒ 次に挙げるいずれか — 初期~時は `未定義^i とする 【`登録-済み$になった時点で、他の値に更新される】 ⇒# `未定義^i / `一個^i / `複数個^i ◎ A DOMString observer type which is initially "undefined".
- `落とされた~entry群を要求するか@pO ⇒ 真偽値 — 初期~時は ~F とする。 ◎ A boolean requires dropped entries which is initially set to false.
-
`~option群~list@pO ⇒ `PerformanceObserverInit$I 辞書たちが成す~list, または ε (なし)。 初期~時は ε とする。 `登録-済み$である間は非 ε になる。
【 原文では、 “登録-済み処理能~観測器” という構造体を別に定義して,それに — `処理能~観測器$への参照とともに — `~option群~list$pOを保たせているが、 この構造体は,実質的に[ 処理能~観測器は`処理能~観測器~list$内に含まれるか否か ]を表現するだけに過ぎず,無為に冗長なので、 この訳では ε を利用して単純~化している。 】
◎ ↓
callback `PerformanceObserverCallback@I = `undefined$ ( `PerformanceObserverEntryList$I %entries, `PerformanceObserver$I %observer, optional `PerformanceObserverCallbackOptions$I %options = {} ); [`Exposed$=(Window,Worker)] interface `PerformanceObserver@I { `constructor$(`PerformanceObserverCallback$I %callback); `undefined$ `observe$m(optional `PerformanceObserverInit$I %options = {}); `undefined$ `disconnect$m(); `PerformanceEntryList$I `takeRecords$m(); [`SameObject$] static readonly attribute `FrozenArray$<`DOMString$> `supportedEntryTypes$m; };
注記: 処理能~overheadを最小に保つためには、 ~appは,関心ある~event型【`~entry型$】のみを申込んで、 処理能~dataを観測する必要がなくなったなら,観測器を `disconnect()$m するべきである。 名前( `name$m )による絞込みは~supportされない — それは、[ 暗黙的にすべての~event型を申込む結果,大量の~eventを生成することになる ]ので,アリではあるが忌避される。 ◎ Note To keep the performance overhead to minimum the application ought to only subscribe to event types that it is interested in, and disconnect the observer once it no longer needs to observe the performance data. Filtering by name is not supported, as it would implicitly require a subscription for all event types — this is possible, but discouraged, as it will generate a significant volume of events.
5.1. `PerformanceObserverCallbackOptions^I 辞書
dictionary `PerformanceObserverCallbackOptions@I { unsigned long long `droppedEntriesCount$d; };
- `droppedEntriesCount@d
- [ 当の`処理能~観測器$の`落とされた~entry群を要求するか$pO ~EQ ~T ]の場合 【 ~EQ ~F の場合,この~memberは無い】、 次を表現している整数 ⇒ 観測器が観測している`~entry型$を伴う~entryのうち落とされたものの個数 ◎ An integer representing the dropped entries count for the entry types that the observer is observing when the PerformanceObserver's requires dropped entries is set.
5.2. `observe()^m ~method
`observe()$m ~methodは、 コレが`登録-済み$であれば コレを更新し,そうでなければコレを`登録-済み$にする。 ◎ The observe() method instructs the user agent to register the observer and\
`observe(options)@m ~method手続きは: ◎ must run these steps: • Let relevantGlobal be this's relevant global object.
- %型~群 ~LET %options[ "`entryTypes$d" ] ◎ ↓
- %型 ~LET %options[ "`type$d" ] ◎ ↓
- ~IF[ %型~群 ~EQ ε ]~AND[ %型 ~EQ ε ] ⇒ ~THROW `TypeError$E ◎ If options's entryTypes and type members are both omitted, then throw a "TypeError".
- ~IF[ %型~群 ~NEQ ε ]~AND[ %options に `entryTypes$d 以外の~memberは在る ] ⇒ ~THROW `TypeError$E ◎ If options's entryTypes is present and any other member is also present, then throw a "TypeError".
-
コレの`種別$pOに応じて: ◎ Update or check this's observer type by running these steps:
- `未定義^i ⇒ コレの`種別$pO ~SET [ %型~群 ~NEQ ε ならば `複数個^i / ~ELSE_ `一個^i ] ◎ If this's observer type is "undefined": • If options's entryTypes member is present, then set this's observer type to "multiple". • If options's type member is present, then set this's observer type to "single".
- `一個^i ⇒ ~IF[ %型~群 ~NEQ ε ] ⇒ ~THROW `InvalidModificationError$E ◎ If this's observer type is "single" and options's entryTypes member is present, then throw an "InvalidModificationError".
- `複数個^i ⇒ ~IF[ %型 ~NEQ ε ] ⇒ ~THROW `InvalidModificationError$E ◎ If this's observer type is "multiple" and options's type member is present, then throw an "InvalidModificationError".
- %大域~obj ~LET コレに`関連な大域~obj$ ◎ ↑↑
- %観測器~list ~LET %大域~obj の`処理能~観測器~list$ ◎ ↓
- %~supportする~entry型~群 ~LET %大域~obj が`~supportする~entry型~群$ ◎ ↓
- コレの`落とされた~entry群を要求するか$pO ~SET ~T ◎ Set this's requires dropped entries to true.
-
~IF[ コレの`種別$pO ~EQ `複数個^i ]: ◎ If this's observer type is "multiple", run the following steps: • Let entry types be options's entryTypes sequence.
-
%型~群 を成す ~EACH( %~entry型 ) に対し ⇒ ~IF[ %~entry型 ~NIN %~supportする~entry型~群 ] ⇒ %型~群 から %~entry型 を除去する ◎ Remove all types from entry types that are not contained in relevantGlobal's frozen array of supported entry types.\
~UAは、 除去された`~entry型$があれば,開発者に通知するベキである — 例えば、 ~console警告にそれらを挙げるのが適切になるであろう。 ◎ The user agent SHOULD notify developers if entry types is modified. For example, a console warning listing removed types might be appropriate.
~IF[
%型~群 は空である
]
⇒
~RET
⇒
~UAは、
登録は中止されたことを開発者に通知するベキである
— 例えば,~console警告が適切になるであろう。
◎
If the resulting entry types sequence is an empty sequence, abort these steps. The user agent SHOULD notify developers when the steps are aborted to notify that registration has been aborted. For example, a console warning might be appropriate.
-
- ~IF[ コレ ~NIN %観測器~list ] ⇒ コレを %観測器~list に付加する ◎ ↓
- コレの`~option群~list$pO ~SET « %options » ◎ If the list of registered performance observer objects of relevantGlobal contains a registered performance observer whose observer is this, replace its options list with a list containing options as its only item. ◎ Otherwise, create and append a registered performance observer object to the list of registered performance observer objects of relevantGlobal, with observer set to this and options list set to a list containing options as its only item.
~ELSE( コレの`種別$pO ~EQ `一個^i ): ◎ Otherwise, run the following steps: • Assert that this's observer type is "single".
-
~IF[ %型 ~NIN %~supportする~entry型~群 ] ⇒ ~RET ◎ If options's type is not contained in the relevantGlobal's frozen array of supported entry types, abort these steps.\
この場合、 ~UAは, これが起きたことを開発者に通知するベキである — 例えば,~console警告を介して。 ◎ The user agent SHOULD notify developers when this happens, for instance via a console warning.
-
~IF[ コレ ~IN %観測器~list ]: ◎ If the list of registered performance observer objects of relevantGlobal contains a registered performance observer obs whose observer is this:
- ~IF[ コレの`~option群~list$pOを成す ある~item %~item は[ %~item[ "`type$d" ] ~EQ %型 ]を満たす ] ⇒ コレの`~option群~list$pO内の %~item を %options に置換する ◎ If obs's options list contains a PerformanceObserverInit item currentOptions whose type is equal to options's type, replace currentOptions with options in obs's options list.
- ~ELSE ⇒ コレの`~option群~list$pOに %options を付加する ◎ Otherwise, append options to obs's options list.
- ~ELSE ⇒# コレを %観測器~list に付加する; コレの`~option群~list$pO ~SET « %options » ◎ Otherwise, create and append a registered performance observer object to the list of registered performance observer objects of relevantGlobal, with observer set to the this and options list set to a list containing options as its only item.
-
~IF[ %options[ "`buffered$d" ] ~EQ ~T ]: ◎ If options's buffered flag is set:
- %~tuple ~LET `処理能~entry~tupleを得る$( %型, %大域~obj ) ◎ Let tuple be the relevant performance entry tuple of options's type and relevantGlobal.
- %~tuple の`処理能~entry~buffer$を成す ~EACH( %~entry ) に対し ⇒ ~IF[ `~entryを追加するべきか?$( %~entry, %options ) ~EQ ~T ] ⇒ コレの`~buffer$pOに %~entry を`付加する$ ◎ For each entry in tuple's performance entry buffer: • If should add entry with entry and options as parameters returns true, append entry to the observer buffer.
- `処理能~観測器~taskを~queueする$( %大域~obj ) ◎ Queue the PerformanceObserver task with relevantGlobal as input.
注記: 同じ `PerformanceObserver$I ~obj上で `observe(options)$m を~callするときは、 %options の[ `entryTypes$d, `type$d ]のうち,~~一貫して片方のみを利用する必要がある — 例えば `observe()$m を `entryTypes$d を与えて~callしてから, `type$d を与えて また~callした場合、 例外が投出される。 これには、 ~callがどう積重なるかについて混同を避けることが意味されている: ◎ Note A PerformanceObserver object needs to always call observe() with options's entryTypes set OR always call observe() with options's type set. If one PerformanceObserver calls observe() with entryTypes and also calls observe with type, then an exception is thrown. This is meant to avoid confusion with how calls would stack.\
- `entryTypes$d を利用する下では【すなわち, `種別$pO ~EQ `複数個^i 】 ⇒ `PerformanceObserverInit$I 内の他の~memberは利用できないことに加え、 後方-互換性を得るため,複数回の `observe()$m ~callは 以前のそれを上書きすることになる — この事例では一回の~callで足りるべきなので。 ◎ When using entryTypes, no other parameters in PerformanceObserverInit can be used. In addition, multiple observe() calls will override for backwards compatibility and because a single call should suffice in this case.\
- `type$d を利用する下では【すなわち, `種別$pO ~EQ `一個^i 】 ⇒ 1 回の~callは 1 個の`~entry型$のみ指定するので,各~callは積重なることになる。 この場合も、 同じ `type$d を与えて `observe()$m を繰返して~callしたときは,上書きすることになる。 ◎ On the other hand, when using type, calls will stack because a single call can only specify one type. Calling observe() with a repeated type will also override.
5.2.1. `PerformanceObserverInit^I 辞書
dictionary `PerformanceObserverInit@I { `sequence$<`DOMString$> `entryTypes$d; DOMString `type$d; boolean `buffered$d; };
- `entryTypes@d
- 観測されることになる`~entry型$たちが成す~listを与える。 この~listが在る場合、 空であってはナラナイ, かつ 他のすべての~memberも在ってはナラナイ。 ~UAは、 この~list内の型のうち,自身が認識しないものは無視するモノトスル。 ◎ A list of entry types to be observed. If present, the list MUST NOT be empty and all other members MUST NOT be present. Types not recognized by the user agent MUST be ignored.
- `type@d
- 観測されることになる単独の`~entry型$を与える。 ~UAは、 自身が認識しない型を無視するモノトスル。 ◎ A single entry type to be observed. A type that is not recognized by the user agent MUST be ignored. Other members may be present.
- `buffered@d
- 次を指示する~flag ⇒ ~bufferされた~entryは、 観測器の~bufferに~queueされるべきか否か ◎ A flag to indicate whether buffered entries should be queued into observer's buffer.
5.2.2. `PerformanceObserverEntryList^I ~interface
[`Exposed$=(Window,Worker)] interface `PerformanceObserverEntryList@I { `PerformanceEntryList$I `getEntries$mO(); `PerformanceEntryList$I `getEntriesByType$mO(`DOMString$ %type); `PerformanceEntryList$I `getEntriesByName$mO(`DOMString$ %name, optional `DOMString$ %type); };
各 `PerformanceObserverEntryList$I ~objには、 `~entry~list@ が結付けられる。 それは、 `PerformanceEntryList$I ~objであり,構築~時に初期化される 【`処理能~観測器~taskを~queueする$とき,~queueされる~task内で】 。 ◎ Each PerformanceObserverEntryList object has an associated entry list, which consists of a PerformanceEntryList and is initialized upon construction.
`getEntries()@mO ~method手続きは ⇒ ~RET `~bufferを名前と型で絞込む$( コレの`~entry~list$, ~NULL, ~NULL )
◎ 5.2.2.1 getEntries() method ◎ Returns a PerformanceEntryList object returned by filter buffer by name and type algorithm with this's entry list, name and type set to null.`getEntriesByType(type)@mO ~method手続きは ⇒ ~RET `~bufferを名前と型で絞込む$( コレの`~entry~list$, ~NULL, %type )
◎ 5.2.2.2 getEntriesByType() method ◎ Returns a PerformanceEntryList object returned by filter buffer by name and type algorithm with this's entry list, name set to null, and type set to the method's input type parameter.`getEntriesByName(name, type)@mO ~method手続きは:
- ~IF[ %type ~EQ ε ] ⇒ %type ~SET ~NULL
- ~RET `~bufferを名前と型で絞込む$( コレの`~entry~list$, %name, %type )
5.3. `takeRecords()^m
`takeRecords()@m ~method手続きは:
- %複製 ~LET コレの`~buffer$pOの複製
- コレの`~buffer$pOを空にする
- ~RET %複製
5.4. `disconnect()^m ~method
`disconnect()@m ~method手続きは: ◎ The disconnect() method must do the following:
- コレに`関連な大域~obj$の`処理能~観測器~list$から,コレを除去する ◎ Remove this from the list of registered performance observer objects of relevant global object.
- コレの`~buffer$pOを空にする ◎ Empty this's observer buffer.
- コレの`~option群~list$pO ~SET ε【!空にする】 ◎ Empty this's options list.
5.5. `supportedEntryTypes^m 属性
各 `大域~obj$には、 `~supportする~entry型~群@ が結付けられる。 それは、 ~alphabet-順序による文字列たちからなるよう初期化された `FrozenArray$I であり,[ 当の大域~obj用に~supportするものとして`~registry$に含まれる`~entry型$たち ]から作成される。 ◎ Each global object has an associated frozen array of supported entry types, which is initialized to the FrozenArray created from the sequence of strings among the registry that are supported for the global object, in alphabetical order.
注記: この属性は、[ どの`~entry型$を,~UAが~supportするか ]を容易に知ることを,~web開発者に許容する。 ◎ Note This attribute allows web developers to easily know which entry types are supported by the user agent.
6. 処理
6.1. `PerformanceEntry^I を~queueする
`処理能~entryを~queueする@ ときは、 所与の ( `PerformanceEntry$I ~obj %新たな~entry ) に対し,次を走らす: ◎ To queue a PerformanceEntry (newEntry), run these steps:
-
~IF[ %新たな~entry の `id$m は未設定である ]: ◎ If newEntry's id is unset:
- %~ID ~LET `~IDを生成する$( %新たな~entry ) ◎ Let id be the result of running generate an id for newEntry.
- %新たな~entry の `id$m ~SET %~ID ◎ Set newEntry's id to id.
- %~entry型 ~LET %新たな~entry の `entryType$m 値 ◎ ↓↓Let interested observers be an initially empty set of PerformanceObserver objects. ◎ Let entryType be newEntry’s entryType value.
- %大域~obj ~LET %新たな~entry に`関連な大域~obj$ ◎ Let relevantGlobal be newEntry's relevant global object.
-
~IF[ %大域~obj には`結付けられた文書$がある 【 %大域~obj は`~window$である】 ] ⇒ %新たな~entry の `navigationId$m ~SET %大域~obj に`結付けられた文書$の`最も近過去な~navi$†の `id$m † ◎ If relevantGlobal has an associated document: • Set newEntry's navigationId to the value of relevantGlobal's associated document's most recent navigation's id.
【† これらが未設定な場合の挙動は指定されていない。 他の仕様のどこかで、 そうならないよう施行されると思われる (例えば,`処理能~entryを~queueする$手続きを介して)。 】
-
~ELSE ⇒ %新たな~entry の `navigationId$m ~SET ~NULL
【† `navigationId$m は ~NULL を返し得ないので、 ~accessされる前に,他の仕様のどこかで、 ~NULL 以外に設定されると思われる (例えば,`~navi処理能~entryを~queueする$手続きを介して)。 】
◎ Otherwise, set newEntry's navigationId to null. - %大域~obj の`処理能~観測器~list$を成す ~EACH( `処理能~観測器$ %観測器 ) に対し ⇒ ~IF[ %観測器 の`~option群~list$pOを成す ある~item %~option群 は[ %~entry型 ~IN %~option群[ "`entryTypes$d" ] ~NEQ ε ]~OR[ %~entry型 ~EQ %~option群[ "`type$d" ] ~NEQ ε ]を満たす【該当する %~option群 は在っても 1 個に限られる( `observe()$m を見よ)】 ] ⇒ ~IF[ `~entryを追加するべきか?$( %新たな~entry, %~option群 ) ~EQ ~T ] ⇒ %観測器 の`~buffer$pOに %新たな~entry を付加する ◎ For each registered performance observer regObs in relevantGlobal's list of registered performance observer objects: • If regObs's options list contains a PerformanceObserverInit options whose entryTypes member includes entryType or whose type member equals to entryType: •• If should add entry with newEntry and options returns true, append regObs's observer to interested observers. ◎ For each observer in interested observers: • Append newEntry to observer's observer buffer.
- %~tuple ~LET `処理能~entry~tupleを得る$( %~entry型, %大域~obj ) ◎ Let tuple be the relevant performance entry tuple of entryType and relevantGlobal.
- %~bufferは満杯か ~LET `~bufferは満杯かどうか決定する$( %~tuple ) ◎ Let isBufferFull be the return value of the determine if a performance entry buffer is full algorithm with tuple as input.
- %追加するべきか ~LET `~entryを追加するべきか?$( %新たな~entry ) ◎ Let shouldAdd be the result of should add entry with newEntry as input.
- ~IF[ %~bufferは満杯か ~EQ ~F ]~AND[ %追加するべきか ~EQ ~T ] ⇒ %~tuple の`処理能~entry~buffer$に %新たな~entry を`付加する$ ◎ If isBufferFull is false and shouldAdd is true, append newEntry to tuple's performance entry buffer.
- `処理能~観測器~taskを~queueする$( %大域~obj ) ◎ Queue the PerformanceObserver task with relevantGlobal as input.
6.3. 処理能~観測器~taskを~queueする
`処理能~観測器~taskを~queueする@ ときは、 所与の ( %大域~obj ) に対し,次を走らす: ◎ When asked to queue the PerformanceObserver task, given relevantGlobal as input, run the following steps:
- ~IF[ %大域~obj の`処理能~観測器~taskは~queue済みか$ ~EQ ~T ] ⇒ ~RET ◎ If relevantGlobal's performance observer task queued flag is set, terminate these steps.
- %大域~obj の`処理能~観測器~taskは~queue済みか$ ~SET ~T ◎ Set relevantGlobal's performance observer task queued flag.
-
`~taskを~queueする$( `処理能~時列線~task~source@ , 次に与える手続き ) ◎ Queue a task that consists of running the following substeps. The task source for the queued task is the performance timeline task source.
手続きは: ◎ ↑
- %大域~obj の`処理能~観測器~taskは~queue済みか$ ~SET ~F ◎ Unset performance observer task queued flag of relevantGlobal.
- %通知-~list ~LET %大域~obj の`処理能~観測器~list$を`~cloneする$ 【~cloneするのは、後~段で~callされる~callbackによる~~影響を避けるため】 ◎ Let notifyList be a copy of relevantGlobal's list of registered performance observer objects.
-
%通知-~list を成す ~EACH( `処理能~観測器$ %観測器 ) に対し: ◎ For each registered performance observer object registeredObserver in notifyList, run these steps: • Let po be registeredObserver's observer.
- ~IF[ %観測器 の`~buffer$pOは空である ] ⇒ ~CONTINUE ◎ ↓
- %~entry群 ~LET %観測器 の`~buffer$pOの複製 ◎ Let entries be a copy of po’s observer buffer. ◎ If entries is empty, return.
- %観測器 の`~buffer$pOを空にする ◎ Empty po’s observer buffer.
- %観測器~entry~list ~LET 新たな `PerformanceObserverEntryList$I ◎ Let observerEntryList be a new PerformanceObserverEntryList,\
- %観測器~entry~list の`~entry~list$ ~SET %~entry群 ◎ with its entry list set to entries.
- %~callback~option群 ~LET 新たな `PerformanceObserverCallbackOptions$I ◎ ↓
-
~IF[ %観測器 の`落とされた~entry群を要求するか$pO ~EQ ~T ]:
- %落とした~entry数 ~LET 0
-
%大域~obj の`処理能~entry~buffer~map$を成す ~EACH( %~entry型 → %~tuple ) に対し:
-
~IF[ %観測器 の`~option群~list$pO内に ~OR↓ を満たす~item %~option群 は在る ]…
- %~entry型 ~IN %~option群[ "`entryTypes$d" ] ~NEQ ε
- %~entry型 ~EQ %~option群[ "`type$d" ] ~NEQ ε
…ならば ⇒ %落とした~entry数 ~INCBY %~tuple の`落とした~entry数$
-
- %観測器 の`落とされた~entry群を要求するか$pO ~SET ~F
- %~callback~option群[ "`droppedEntriesCount$d" ] ~SET %落とした~entry数
-
`~callback関数を呼出す$( ↓ ) 【!原文は単に “Call” 】 ⇒# %観測器 の`~callback$pO, « %観測器~entry~list, %観測器, %~callback~option群 », %観測器
この段の中で例外が`投出-$されたときは【、~catchして】 ⇒ その`例外を報告する$
◎ Call po’s observer callback with observerEntryList as the first argument, with po as the second argument and as callback this value, and with callbackOptions as the third argument. If this throws an exception, report the exception.
`処理能~時列線~task~source$用の`~task~queue$は、 低優先度な~queueである — ~UAは、 処理能~監視~codeの影響iを最小限にするため,アリなら遊休中に処理するべきである。 ◎ The performance timeline task queue is a low priority queue that, if possible, should be processed by the user agent during idle periods to minimize impact of performance monitoring code.
6.4. ~buffer~mapを ( 名前, 型 ) で絞込む
`~buffer~mapを名前と型で絞込む@ ときは、 所与の ( %~obj, %名前, %型 ) に対し,次を走らす: ◎ When asked to run the filter buffer map by name and type algorithm with optional name and type, run the following steps:
- %結果 ~LET 新たな`~list$ ◎ Let result be an initially empty list.
- %~map ~LET %~obj に`関連な大域~obj$の`処理能~entry~buffer~map$ ◎ Let map be the performance entry buffer map associated with the relevant global object of this.
- %~tuple~list ~LET %型 に応じて ⇒# ~NULL ならば %~map の`値~群$ / ~ELSE_ « %~map[ %型 ] » ◎ Let tuple list be an empty list. ◎ If type is not null, append the result of getting the value of entry on map given type as key to tuple list. Otherwise, assign the result of get the values on map to tuple list.
-
%~tuple~list を成す ~EACH( %~tuple ) に対し: ◎ For each tuple in tuple list, run the following steps:
- %~buffer ~LET %~tuple の`処理能~entry~buffer$ ◎ Let buffer be tuple's performance entry buffer.
- ~IF[ %~tuple の`時列線から可用か$ ~EQ ~F ] ⇒ ~CONTINUE ◎ If tuple's availableFromTimeline is false, continue to the next tuple.
- %~entry群 ~LET `~bufferを名前と型で絞込む$( %~buffer, %名前, %型 ) ◎ Let entries be the result of running filter buffer by name and type with buffer, name and type as inputs.
- %結果 を %~entry群 で`拡張する$ ◎ For each entry in entries, append entry to result.
- ~RET %結果 を各~entryの `startTime$m の時系列順に~sortした結果 【!*~INFRA#list-sort-in-ascending-order】 ◎ Sort results's entries in chronological order with respect to startTime ◎ Return result.
6.5. ~bufferを ( 名前, 型 ) で絞込む
`~bufferを名前と型で絞込む@ ときは、 所与の ( %~buffer, %名前, %型 ) に対し,次を走らす: ◎ When asked to run the filter buffer by name and type algorithm, with buffer, name, and type as inputs, run the following steps:
- %~list ~LET 新たな`~list$ ◎ Let result be an initially empty list.
-
%~buffer を成す ~EACH( `PerformanceEntry$I ~obj %~entry ) に対し: ◎ For each PerformanceEntry entry in buffer, run the following steps:
- ~IF[ %型 ~NIN { ~NULL, %~entry の `entryType$m 属性~値 } ] ⇒ ~CONTINUE ◎ If type is not null and if type is not identical to entry's entryType attribute, continue to next entry.
- ~IF[ %名前 ~NIN { ~NULL, %~entry の `name$m 属性~値 ) ] ⇒ ~CONTINUE ◎ If name is not null and if name is not identical to entry's name attribute, continue to next entry.
- %~list に %~entry を`付加する$ ◎ append entry to result.
- ~RET %~list を 各~entryの `startTime$m の時系列順に~sortした結果 【!*~INFRA#list-sort-in-ascending-order】 ◎ Sort results's entries in chronological order with respect to startTime ◎ Return result.
6.6. ~bufferは満杯かどうか決定する
`~bufferは満杯かどうか決定する@ ときは、 所与の ( %~tuple ) に対し,次を走らす: ◎ To determine if a performance entry buffer is full, with tuple as input, run the following steps:
- ~IF[ %~tuple の`処理能~entry~buffer$の~size ~LT %~tuple の`最大~buffer~size$ ] ⇒ ~RET ~F ◎ Let num current entries be the size of tuple's performance entry buffer. ◎ If num current entries is less than tuples's maxBufferSize, return false.
- %~tuple の`落とした~entry数$ ~INCBY 1 ◎ Increase tuple's dropped entries count by 1.
- ~RET ~T ◎ Return true.
6.7. 処理能~entry~IDを生成する
`~IDを生成する@ ときは、 所与の ( `PerformanceEntry$I %~entry ) に対し,次の手続きを走らす: ◎ When asked to generate an id for a PerformanceEntry entry, run the following steps:
- %大域~obj ~LET %~entry に`関連な大域~obj$ ◎ Let relevantGlobal be entry's relevant global object.
- %大域~obj の`最後の処理能~entry~ID$ ~INCBY ~UAが選ぶ小さな整数 ◎ Increase relevantGlobal's last performance entry id by a small number chosen by the user agent.
- ~RET %大域~obj の`最後の処理能~entry~ID$ ◎ Return relevantGlobal's last performance entry id.
~UAは、 `最後の処理能~entry~ID$を増やす小さな整数を毎回~randomに変えてもヨイ。 ~UAは、[ どの大域~objに対しても,その`最後の処理能~entry~ID$を同じ一定な整数で増やす ]ようにしないモノトスル — そうすると,非同一-生成元への漏洩を導入し得るので。 ◎ A user agent may choose to increase the last performance entry idit by a small random integer every time. A user agent must not pick a single global random integer and increase the last performance entry id of all global objects by that amount because this could introduce cross origin leaks.
注記: `最後の処理能~entry~ID$は、 ~randomな初期~値をとり,~UAが選ぶ小さな整数で増やされる — 開発者が,それを[ ~web~app内で生成された~entryの個数を与える~counter ]と見なすことを忌避するため。 ◎ Note The last performance entry id has an initial random value, and is increased by a small number chosen by the user agent instead of 1 to discourage developers from considering it as a counter of the number of entries that have been generated in the web application.
7. ~privacyの考慮点
この仕様は、 `HR-TIME-3$r に定義された `Performance$I ~interfaceを拡張して,`処理能~時列線$[ に~entryを~queueする/から~entryを検索取得する ]ための~methodを供する。 高-分解能な計時~情報を公開することによる~privacyの考慮点については、 `HR-TIME-3$r を参照rされたし。 新たな各~仕様も、 新たな処理能~entryを導入しているならば,自前の~security考慮点を与えるベキである ◎ This specification extends the Performance interface defined by [HR-TIME-3] and provides methods to queue and retrieve entries from the performance timeline. Please refer to [HR-TIME-3] for privacy considerations of exposing high-resoluting timing information. Each new specification introducing new performance entries should have its own privacy considerations as well.
`最後の処理能~entry~ID$は、 故意に~randomな値に初期化され, 新たな `PerformanceEntry$I が~queueされる毎回ごとに別の小さな値で増分される。 ~UAは、 利用する増分として[ すべての利用者~用に一貫した量/ 各`大域~obj$に異なる量/ 各 `PerformanceEntry$I に新たな~randomな量 ]を選んでもヨイ。 しかしながら,[ 非同一-生成元への漏洩を防止する/ これが指紋収集を可能化しないことを確保する ]ため、 ~UAは,[ すべての`大域~obj$にまたがる,すべての `PerformanceEntry$I ~obj ]用に同じ一定な増分を利用しないモノトスル。 ◎ The last performance entry id is deliberately initialized to a random value, and is incremented by another small value every time a new PerformanceEntry is queued. User agents may choose to use a consistent increment for all users, or may pick a different increment for each global object, or may choose a new random increment for each PerformanceEntry. However, in order to prevent cross-origin leaks, and ensure that this does not enable fingerprinting, user agents must not just pick a unique random integer, and use it as a consistent increment for all PerformanceEntry objects across all global objects.
8. ~securityの考慮点
この仕様は、 `HR-TIME-3$r に定義された `Performance$I ~interfaceを拡張し,`処理能~時列線$[ に~entryを~queueする/から~entryを検索取得する ]ための~methodを供する。 高-分解能な計時~情報を公開することによる~securityの考慮点については、 `HR-TIME-3$r を参照rされたし。 新たな各~仕様も、 新たな処理能~entryを導入しているならば,自前の~security考慮点を伴うベキである ◎ This specification extends the Performance interface defined by [HR-TIME-3] and provides methods to queue and retrieve entries from the performance timeline. Please refer to [HR-TIME-3] for security considerations of exposing high-resoluting timing information. Each new specification introducing new performance entries should have its own security considerations as well.
9. 依存関係
【 他の仕様に定義される用語(の一部)。 この節の和訳は、 省略する。 】 ◎ The [INFRA] specification defines the following: key, getting the value of an entry.
謝辞
この仕様に貢献された次の方々に: