1. 序論
~pageが読込まれるに伴い, および利用者が読込まれた~pageとヤリトリする間、[ ~app, ~browser ]の両者とも,後で~browserにより実行されるような様々な~eventを~queueする — 例えば: ~UAは、 利用者の活動に基づいて入力~eventを~scheduleする / ~appは、 `requestAnimationFrame()$m 用の~callbackや他の~callback, 等々を~scheduleする。 ~queueされたこれらの~eventは、 ~browserにより 1 個ずつ~dequeueされ, 実行される。 ◎ As the page is loading and while the user is interacting with the page afterwards, both the application and browser queue various events that are then executed by the browser -- e.g. user agent schedules input events based on user’s activity, the application schedules callbacks for requestAnimationFrame and other callbacks, etc. Once in the queue, the browser dequeues these events one-by-one and executes them.
しかしながら,~taskには長い時間(複数の~frame)かかり得るものもあり、 それが起きた場合/とき, ~UI~threadは阻まれ,他のすべての~taskも阻まれる結果になり得る。 これは、 利用者からは[ 利用者~入力に対し~browserが応答-不能になり,~pageから “締め出される” ]ことにより,共通的に可視になる。 今日における~web上の不良な利用者~体験の大多数は、 それが~sourceにある: ◎ However, some tasks can take a long time (multiple frames) and if/when that happens, the UI thread may become blocked and block all other tasks as well. To the user, this is commonly visible as a "locked up" page where the browser is unable to respond to user input; this is a major source of bad user experience on the web today:
- “ヤリトリ可能になる時機” が遅延される: ◎ Delayed "time to Interactive":
- ~pageが読込まれる間,あるいは視覚的には完全に具現化されていても、 長い~taskは~main~thread†と~~連携することが多い — その結果、 利用者は~pageとヤリトリできなくなる。 よくある元凶として、 拙く設計された第三者-主体の内容が挙げられる。 ◎ while the page is loading, or even completely visually rendered, long tasks often tie up the main thread and prevent the user from interacting with the page. Poorly designed third-party content is frequently the culprit.
- 【† `~event~loopの処理@~WAPI#event-loop-processing-model$を遂行する~thread (`概略的な説明@https://developer.mozilla.org/docs/Glossary/Main_thread$)。 】
- 入力の待時間が~~長い/可変: ◎ High/variable input latency:
- ~criticalな利用者~対話~event (例: `tap^en, `click^en, `scroll^en, `wheel^en, 等々) は、 長い~taskの背後に~queueされ,即応しない — その結果、 利用者~体験は予測-不能になる。 ◎ critical user-interaction events (e.g. tap, click, scroll, wheel, etc.) are queued behind long tasks which yields janky and unpredictable user experience.
- ~event取扱いの待時間が~~長い/可変: ◎ High/variable event handling latency:
- 入力~同様、 ~event~callback(例: `onload^et ~event, 等々)の処理は, ~appの更新を遅延する。 ◎ like input, processing event callbacks (e.g. onload events, etc.) delay application updates.
- 即応しない[ ~animation/~scrolling ]: ◎ Janky animations and scrolling:
- 一部の[ ~animation/~scrolling ]は、 組成器と~main~threadとの間の協調を要求する — 長い~taskが~main~threadを阻んでいる場合、[ ~animation/~scrolling ]の応答性に影響し得る。 ◎ some animation and scrolling interactions require coordination between compositor and main threads; if a long task is blocking the main thread it can affect responsiveness of animations and scrolling.
一部の~app (および `RUM@https://en.wikipedia.org/wiki/Real_user_monitoring$ ~vendor 【 `real user monitoring^en / “現実の利用者~体験の監視” 】 )は、 すでに, “長い~task” が起こる事例を識別して追跡しようと試みている。 一例として、 短い周期的な~timerを~installした上で,各~満了から次回の満了までに経過した時間を検分する~patternが知られている。 経過した時間が~timer周期を超えるならば、 1 個~以上の長い~taskが~event~loopの実行を遅延させた見込みが高いことになる。 この~approachは、 大体は働くが,いくつかの点で処理能に~~悪影響を及ぼす: ◎ Some applications (and RUM vendors) are already attempting to identify and track cases where "long tasks" happen. For example, one known pattern is to install a short periodic timer and inspect the elapsed time between the successive expirations: if the elapsed time is greater than the timer period, then there is high likelihood that one or more long tasks have delayed execution of the event loop. This approach mostly works but has several bad performance implications:\
- 長い~taskを検出するために~pollし続けることにより、 ~appが遊休~時に走らす~codeに割り当てられる “静止期間” が細切れになる ( `requestIdleCallback()$m を見よ)。 ◎ by polling to detect long tasks, the application prevents quiescence and long idle blocks (see requestIdleCallback);\
- ~batteryが短命になる。 ◎ it’s bad for battery life;\
- 何が遅延させているか知るすべが無い (例:当事者-主体, 第三者-主体 どちらの~codeか?)。 ◎ there is no way to know what is causing the delay (e.g. first party or third party code).
`RAIL@https://developers.google.com/web/fundamentals/performance/rail$ ( `Response Animation Idle Load^en )処理能~modelから、[ ~appは,利用者~入力に対し 100ms 以内に応答するべきである ]と示唆されている (~touchによる移動-や~scrollingにおいては 16ms 以内)。 この~APIの目標は、 この~~目的に抵触し得る~taskについての通知を表面化することである。 この~APIは、 50ms 以上かかる~taskを表面化する。 そのような~taskを伴わない~web~siteならば、 利用者~入力に対し — それを受信した時点で実行-中な~taskが完遂するまで 50ms 未満, それに反応する~taskを実行するのも 50ms 未満になるので — 100ms 以内に応答することになるはずである。 ◎ The RAIL performance model suggests that applications should respond to user input in less than 100ms (for touch move and scrolling, the threshold is 16ms). The goal of this API is to surface notifications about tasks that may prevent the application from hitting these targets. This API surfaces tasks that take 50ms or more. A website without these tasks should respond to user input in under 100ms: it will take less than 50ms to finish the task that is being executed when the user input is received and less than 50ms to execute the task to react to such user input.
1.1. 用例
const %observer = new PerformanceObserver(function(%list) { for (const %entry of %list.getEntries()) { /* 長い~task通知を処理する:解析と監視~用に報告する… ◎ Process long task notifications: report back for analytics and monitoring ... */ } }); /* これまで, および未来における長い~taskの通知~用に,観測器を登録する ◎ Register observer for previous and future long task notifications. */ %observer.observe({type: "longtask", buffered: true}); /* 以降,長い~script実行が生じたときは、 観測器にて `longtask^l ~entryが~queueされ,受信されるようになる。 ◎ Long script execution after this will result in queueing and receiving "longtask" entries in the observer. */
2. 各種用語
`長い~task@ ( `long task^en )とは、 次に挙げるもののうち,所要時間が 50ms を超過するものを指す: ◎ Long task refers to any of the following occurrences whose duration exceeds 50ms:
- ~event~loop`~task$ 【`~event~loop処理~model$の最初の段で選ばれる~task】 と直後の`小task~checkpointを遂行する$ 段。 これは、 ある~event~loop`~task$の所要時間を — それに結付けられた`小task$も含めて — 捕捉する。 ◎ An event loop task plus the perform a microtask checkpoint that follows immediately afterwards. This captures the duration of an event loop task, including its associated microtasks.
- `~event~loop処理~model$の中の`描画を更新する手続き$。 ◎ An update the rendering step within the event loop processing model.
- `~event~loop処理~model$の最後の段から次回の最初の段までにおける静止。 これは、[ `~event~loop$の外側にある~UAの~UI~thread ]内で~UAが遂行する作業を捕捉する。 ◎ A pause between the last step and the next first step of the event loop processing model. This captures any work that the user agent performs in its UI thread outside of the event loop.
所与の`閲覧~文脈$ %閲覧~文脈 用の `閲覧~文脈~容器@ は、 %閲覧~文脈 にて`作動中な文書$navの`~node~navigable$の`容器$navである。 ◎ The browsing context container for a browsing context bc is bc’s active document's node navigable's container.
注記: これは,【~HTMLから】廃された用語であり、 この仕様を改修するときには,新たな用語が再利用されるべきである。 ◎ Note: This term is outdated, and the new terms should be reused when revamping this.
【 この仕様には、[ 他にも,実質的に廃された用語を利用している箇所/ `閲覧~文脈$と`~navigable$を一緒くたに (およそ、 `~navigable$と,それにて`作動中な閲覧~文脈$navを同一視するような形で) 扱っている箇所 ]がいくつかある。 】
`元凶~閲覧~文脈~容器@ ( `culprit browsing context container^en )とは、 ある`長い~task$に全体的に~~関与している`閲覧~文脈~容器$( `iframe$e, `object$e, 等々)を指す。 ◎ Culprit browsing context container refers to the browsing context container (iframe, object, etc.) that is being implicated, on the whole, for a long task.
`長い~task$の `帰属@ ( `attribution^en )とは、 次を識別するものを指す ⇒ 長い~taskに有意に寄与した作業の種別( ~script, ~layoutなど), および その作業を担当していた`元凶~閲覧~文脈~容器$ ◎ Attribution refers to identifying the type of work (such as script, layout etc.) that contributed significantly to the long task, as well as identifying which culprit browsing context container is responsible for that work.
【この訳に特有な表記規約】
◎表記記号ms は、 ミリ秒単位( `milliseconds^en )を表す。
3. 長い~taskの計時
長い~taskの計時は、 この節に与える新たな~interfaceを孕む。 ◎ Long Task timing involves the following new interfaces:
3.1. `PerformanceLongTaskTiming^I ~interface
[`Exposed$=Window]
interface `PerformanceLongTaskTiming@I : `PerformanceEntry$I {
/*
`PerformanceEntry$I の~memberを多重定義する:
◎
Overloading PerformanceEntry
*/
readonly attribute `DOMHighResTimeStamp$I `startTime$m1;
readonly attribute `DOMHighResTimeStamp$I `duration$m1;
readonly attribute `DOMString$ `name$m1;
readonly attribute `DOMString$ `entryType$m1;
readonly attribute `FrozenArray$<`TaskAttributionTiming$I> `attribution$m;
[`Default$] `object$ `toJSON@m1();
};
`PerformanceLongTaskTiming$I の各種 属性の値は、 `長い~taskを報告する$処理~modelにて設定される。 それらがどう設定されるかについて,規範的でない要約を以下に供する: ◎ The values of the attributes of a PerformanceLongTaskTiming are set in the processing model in § 4.1 Report long tasks. The following provides an informative summary of how they will be set.
-
`name@m1 【!`name$m】 属性の取得子は、[ 当の長い~taskが出自にしているのは、 どの`閲覧~文脈$の中の~event~loop`~task$か ]に応じて,次に挙げるいずれかの文字列を返すことになる: ◎ The name attribute’s getter will return one of the following strings:
- `unknown@l
- ~UAが`~event~loop$の外側で遂行した作業 ◎ The long task originated from work that the user agent performed outside of the event loop.
- `self@l
- この`閲覧~文脈$。 ◎ The long task originated from an event loop task within this browsing context.
- `same-origin-ancestor@l
- `同一-生成元$に属する`先祖~navigable$。 ◎ The long task originated from an event loop task within a same-origin ancestor navigable.
- `same-origin-descendant@l
- `同一-生成元$に属する`子孫~閲覧~文脈$。 ◎ The long task originated from an event loop task within a same-origin descendant browsing context.
- `same-origin@l
- `同一-生成元$に属するが,先祖でも子孫でもない`閲覧~文脈$。 ◎ The long task originated from an event loop task within a same-origin browsing context that is not an ancestor or descendant.
- `cross-origin-ancestor@l
- `同一-生成元$に属さない`先祖~navigable$。 ◎ The long task originated from an event loop task within a cross-origin ancestor navigable.
- `cross-origin-descendant@l
- `同一-生成元$に属さない`子孫~閲覧~文脈$。 ◎ The long task originated from an event loop task within a cross-origin descendant browsing context.
- `cross-origin-unreachable@l
- `同一-生成元$に属さない, かつ先祖でも子孫でもない`閲覧~文脈$。 ◎ The long task originated from an event loop task within a cross-origin browsing context that is not an ancestor or descendant.
- `multiple-contexts@l
- ~event~loop`~task$のうち,複数の`閲覧~文脈$を孕んでいるもの。 ◎ The long task originated from an event loop task involving multiple browsing contexts.
注記: これらの名前には、 一貫性に欠くものがある — `-unreachable^l, `-contexts^l 接尾辞など。 これらの名前は、 後方-互換性の理由から保たれる。 ◎ Note: There are some inconsistencies across these names, such as the "-unreachable" and the "-contexts" suffixes. These names are kept for backward compatibility reasons.
- `entryType@m1 属性の取得子は、 `longtask^l を返す。 ◎ The entryType attribute’s getter step is to return "longtask".
- `startTime@m1 属性の取得子は、 当の~taskが開始された時点を表す `DOMHighResTimeStamp$I 値を返す。 ◎ The startTime attribute’s getter step is to return a DOMHighResTimeStamp of when the task started.
- `duration@m1 属性の取得子は、 当の~taskの開始から終了までに経過した時間を粒度 1ms で表す `DOMHighResTimeStamp$I 値を返す。 ◎ The duration attribute’s getter step is to return a DOMHighResTimeStamp equal to the elapsed time between the start and end of task, with a 1 ms granularity.
- `attribution@m 属性の取得子は、 一連の `TaskAttributionTiming$I ~entryからなる凍結d配列を返す。 ◎ The attribution attribute’s getter will return a frozen array of TaskAttributionTiming entries.
3.2. `TaskAttributionTiming^I ~interface
[`Exposed$=Window]
interface `TaskAttributionTiming@I : `PerformanceEntry$I {
/*
`PerformanceEntry$I の~memberを多重定義する:
◎
Overloading PerformanceEntry
*/
readonly attribute `DOMHighResTimeStamp$I `startTime$m1;
readonly attribute `DOMHighResTimeStamp$I `duration$m1;
readonly attribute `DOMString$ `name$m1;
readonly attribute `DOMString$ `entryType$m1;
readonly attribute `DOMString$ `containerType$m;
readonly attribute `DOMString$ `containerSrc$m;
readonly attribute `DOMString$ `containerId$m;
readonly attribute `DOMString$ `containerName$m;
[`Default$] `object$ `toJSON@m1();
};
`TaskAttributionTiming$I の各種~属性の値は、 `長い~taskを報告する$処理~modelにて設定される。 それらがどう設定されるかについて,規範的でない要約を以下に供する: ◎ The values of the attributes of a TaskAttributionTiming are set in the processing model in § 4.1 Report long tasks. The following provides an informative summary of how they will be set.
- `name@m1 属性の取得子は、 常に `unknown^l を返す。 ◎ The name attribute’s getter will always return "unknown".
- `entryType@m1 属性の取得子は、 常に `taskattribution^l を返す。 ◎ The entryType attribute’s getter will always return "taskattribution".
- `startTime@m1 属性の取得子は、 常に 0 を返す。 ◎ The startTime attribute’s getter will always return 0.
- `duration@m1 属性の取得子は、 常に 0 を返す。 ◎ The duration attribute’s getter will always return 0.
- `containerType@m 属性の取得子は、 `元凶~閲覧~文脈~容器$の型を返す — `iframe^l, `embed^l, `object^l など。 `元凶~閲覧~文脈~容器$は一つも見出されない場合、 `window^l を返すことになる。 ◎ The containerType attribute’s getter will return the type of the culprit browsing context container, such as "iframe", "embed", or "object". If no single culprit browsing context container is found, it will return "window".
- `containerName@m 属性の取得子は、 `元凶~閲覧~文脈~容器$の `name^a 内容~属性の値を返す。 `元凶~閲覧~文脈~容器$は一つも見出されない場合、 空~文字列を返すことになる。 ◎ The containerName attribute’s getter will return the value of the container’s name content attribute. If no single culprit browsing context container is found, it will return the empty string.
- `containerId@m 属性の取得子は、 `元凶~閲覧~文脈~容器$の `id^a 内容~属性の値を返す。 `元凶~閲覧~文脈~容器$は一つも見出されない場合、 空~文字列を返すことになる。 ◎ The containerId attribute’s getter will return the value of the container’s id content attribute. If no single culprit browsing context container is found, it will return the empty string.
- `containerSrc@m 属性の取得子は、 `元凶~閲覧~文脈~容器$の `src^a 内容~属性の値を返す。 `元凶~閲覧~文脈~容器$は一つも見出されない場合、 空~文字列を返すことになる。 ◎ The containerSrc attribute’s getter will return the value of the container’s src content attribute. If no single culprit browsing context container is found, it will return the empty string.
3.3. 元凶を指すもの
◎非規範的`長い~task$は、 異なる種別の作業(~script, ~layout, ~style等々など)を孕み得る。 また、 異なる`閲覧~文脈$の中で実行されることもあれば,大域的な資質を備えるものにもなり得る — [ `~agent~cluster$ / `閲覧~文脈~group集合$ ]全体にわたる長い~garbage収集など。 ◎ A long task can involve different types of work (such as script, layout, style etc), and it could be executed within different browsing contexts, or it could be global in nature such as a long garbage collection that spans the entire agent cluster or browsing context group set.
したがって,`帰属$が指すものには少数の側面fがある: ◎ Thus attribution has a couple of facets:
- 当の長い~taskの生成元や`元凶~閲覧~文脈~容器$の[ 全体の中での所在 ] — これは、 `極小な元凶~帰属@ ( `minimal culprit attribution^en )と称され, `name$m ~fieldにて捕捉される。 ◎ Pointing to the origin of the long task and/or the overall location of the culprit browsing context: this is referred to as minimal culprit attribution and is captured in the name field.
- `長い~task$が孕む作業の種別, およびそれに結付けられた`元凶~閲覧~文脈~容器$ — これは、 `PerformanceLongTaskTiming$I の `attribution$m ~field内の各 `TaskAttributionTiming$I ~objにて捕捉される。 ◎ Pointing to the type of work involved in the long task, and its associated culprit browsing context container: this is captured in TaskAttributionTiming objects in the attribution field of PerformanceLongTaskTiming.
したがって, `PerformanceLongTaskTiming$I 上の[ `name$m, `attribution$m ]~fieldの組は、 長い~taskの~~原因がどこにあるか~~実像を~~描く。 この情報を送達するときには、 ~Webの同一-生成元~施策を固守するモノトスル。 ◎ Therefore, name and attribution fields on PerformanceLongTaskTiming together paint the picture for where the blame rests for a long task. When delivering this information the Web’s same-origin policy must be adhered to.
これらの~fieldは~~相関する — どう関係するかの概観を次に与える: ◎ These fields are not independent. The following gives an overview of how they are related:
`name$m | `attribution$m (`帰属$)に~~関与している`元凶~閲覧~文脈~容器$ |
---|---|
`self$l | 空 |
`same-origin-ancestor$l | 元凶は同一-生成元に属する |
`same-origin-descendant$l | 元凶は同一-生成元に属する |
`same-origin$l | 元凶は同一-生成元に属する |
`cross-origin-ancestor$l | 空 |
`cross-origin-descendant$l | 空 |
`cross-origin-unreachable$l | 空 |
`multiple-contexts$l | 空 |
`unknown$l | 空 |
4. 処理~model
注記: 長い~task用の~APIを実装している~UAは、 その~supportを検出することを開発者に許容するよう, `~window$が`~supportする~entry型~群$【!`supportedEntryTypes$m】に `longtask^l を含める必要がある。 ◎ Note: A user agent implementing the Long Tasks API would need to include "longtask" in supportedEntryTypes for Window contexts, respectively. ◎ This allows developers to detect support for long tasks.
4.1. 長い~taskを報告する
所与の ( %開始~時刻, %終了~時刻, %~top-level閲覧~文脈~群, %~task ) に対し,次の~algoを遂行する: ◎ Given start time, end time, top-level browsing contexts, and task, perform the following algorithm:
- `~task終了~時刻を記録する$( %終了~時刻, %~task の`文書$tK ) ◎ Report task end time given end time and task’s document.
- ~IF[ %終了~時刻 ~MINUS %開始~時刻 ~LT 50ms(長い~taskの閾値) ] ⇒ ~RET ◎ If end time minus start time is less than the long tasks threshold of 50 ms, abort these steps.
- %行先~realm群 ~LET 空~集合 ◎ Let destinationRealms be an empty set.
-
(この段は、 報告の送達-先になる`~realm$の集合を決定する。)
%~top-level閲覧~文脈~群 を成す ~EACH( `~top-level閲覧~文脈$ %T ) に対し:
- %~top-level文書 ~LET %T にて`作動中な文書$nav
- %文書~群 ~LET %~top-level文書 のみからなる集合
- %~top-level文書 の`子孫~閲覧~文脈~list$を成す ~EACH( %子孫 ) に対し ⇒ %文書~群 に %子孫 にて`作動中な文書$navを追加する
- %文書~群 を成す ~EACH( %文書 ) に対し ⇒ %行先~realm群 に次の~tupleを追加する ⇒ ( %文書 に`関連な~realm$, %文書 に`関連な設定群~obj$の`非同一-生成元~能力は隔離されるか?$enV )
-
~UAは、 %行先~realm群 から一部の`~realm$を除去してもヨイ ◎ A user agent may remove some JavaScript Realms from destinationRealms.
注記: この除去は、[ ~UAが別々な~processで取扱っている長い~task ]を`~realm$用に報告するのを避けるために利用できる。 しかしながら、 この概念は精確には指定されていない。 ◎ Note: this removal could be used to avoid reporting long tasks for JavaScript Realms that the user agent handles in a separate process. However, this concept is not specified precisely.
[ どの`文書$から,どの長い~taskが可視になるか ]の視野に関して進行中な論点がある。 なので、 この~logicは,将来に変更され得る。 [`課題 #75@https://github.com/w3c/longtasks/issues/75$] ◎ there is some ongoing discussion regarding the scope of which Documents gain visibility over which long tasks, so this logic could change in the future. [Issue #75]
-
%行先~realm群 を成す ~EACH( ( %行先~realm, %非同一-生成元~能力は隔離されるか ) ) に対し【順序は言及されていない】: ◎ For each (destinationRealm, crossOriginIsolatedCapability) in destinationRealms:
- %名前 ~LET 空~文字列 (これは、 以下で`極小な元凶~帰属$を報告するために利用されることになる) ◎ Let name be the empty string. This will be used to report minimal culprit attribution, below.
- %元凶~設定群 ~LET ~NULL ◎ Let culpritSettings be null.
- %設定群たち ~LET %~task の`~script評価 環境~設定群~obj集合$ ◎ ↓
-
この段は、 %設定群たち を処理して,[ %名前, %元凶~設定群 ]を決定する: ◎ Process task’s script evaluation environment settings object set to determine name and culpritSettings as follows:
- ~IF[ %設定群たち は空である ] ⇒ %名前 ~SET `unknown$l ◎ If task’s script evaluation environment settings object set is empty: set name to "unknown" and culpritSettings to null.
- ~ELIF[ %設定群たち の長さ ~GT 1 ] ⇒ %名前 ~SET `multiple-contexts$l ◎ Otherwise, if task’s script evaluation environment settings object set's length is greater than one: set name to "multiple-contexts" and culpritSettings to null.
-
~ELSE( %設定群たち の長さ ~EQ 1 ): ◎ Otherwise, i.e. if task’s script evaluation environment settings object set's length is one:
- %元凶~設定群 ~SET %設定群たち を成す単独の~item ◎ Set culpritSettings to the single item in task’s script evaluation environment settings object set.
- %行先~設定群 ~LET %行先~realm に`関連な設定群~obj$ ◎ Let destinationSettings be destinationRealm’s relevant settings object. ◎ ↓Let destinationOrigin be destinationSettings’s origin.
- %行先~閲覧~文脈 ~LET %行先~設定群 の`大域~obj$enVに`対応する閲覧~文脈$ ◎ Let destinationBC be destinationSettings’s global object's browsing context.
- %元凶~閲覧~文脈 ~LET %元凶~設定群 の`大域~obj$enVに`対応する閲覧~文脈$ ◎ Let culpritBC be culpritSettings’s global object's browsing context.
- ~Assert: %元凶~閲覧~文脈 ~NEQ ~NULL ◎ Assert: culpritBC is not null.
- ~IF[ %元凶~設定群 ~EQ %行先~設定群 ] ⇒ %名前 ~SET `self$l ◎ If culpritSettings is the same as destinationSettings, set name to "self".
-
~ELIF[ ( %元凶~設定群 の`生成元$enV, %行先~設定群 の`生成元$enV ) は`同一-生成元$である ]: ◎ Otherwise, if culpritSettings’s origin and destinationOrigin are same origin:
- ~IF[ %行先~閲覧~文脈 ~EQ ~NULL ] ⇒ %名前 ~SET `same-origin$l ◎ If destinationBC is null, set name to "same-origin".
- ~ELIF[ %元凶~閲覧~文脈 は %行先~閲覧~文脈 の`先祖~閲覧~文脈$である ] ⇒ %名前 ~SET `same-origin-ancestor$l ◎ Otherwise, if culpritBC is an ancestor of destinationBC, set name to "same-origin-ancestor".
- ~ELIF[ %行先~閲覧~文脈 は %元凶~閲覧~文脈 の`先祖~閲覧~文脈$である ] ⇒ %名前 ~SET `same-origin-descendant$l ◎ Otherwise, if destinationBC is an ancestor of culpritBC, set name to "same-origin-descendant".
- ~ELSE ⇒ %名前 ~SET `same-origin$l ◎ Otherwise, set name to "same-origin".
-
~ELSE: ◎ Otherwise:
- ~IF[ %行先~閲覧~文脈 ~EQ ~NULL ] ⇒ %名前 ~SET `cross-origin-unreachable$l ◎ If destinationBC is null, set name to "cross-origin-unreachable".
-
~IF[ %元凶~閲覧~文脈 は %行先~閲覧~文脈 の`先祖~閲覧~文脈$である ] ⇒# %名前 ~SET `cross-origin-ancestor$l; %元凶~設定群 ~SET ~NULL ◎ Otherwise, if culpritBC is an ancestor of destinationBC, set name to "cross-origin-ancestor" and set culpritSettings to null.
注記: ~securityのため、 これは報告されない。 開発者は、 自身でこれを~~調べるべきである。 ◎ NOTE: this is not reported because of security. Developers should look this up themselves.
- ~ELIF[ %行先~閲覧~文脈 は %元凶~閲覧~文脈 の`先祖~閲覧~文脈$である ] ⇒ %名前 ~SET `cross-origin-descendant$l ◎ Otherwise, if destinationBC is an ancestor of culpritBC, set name to "cross-origin-descendant".
- ~ELSE ⇒ %名前 ~SET `cross-origin-unreachable$l ◎ Otherwise, set name to "cross-origin-unreachable".
- %帰属 ~LET %行先~realm 内の新たな `TaskAttributionTiming$I ~obj ◎ Let attribution be a new TaskAttributionTiming object with destinationRealm\
-
%帰属 の ⇒# `name$m 属性 ~SET `unknown^l【!`unknown$l】, `entryType$m 属性 ~SET `taskattribution^l, `startTime$m 属性 ~SET 0, `duration$m 属性 ~SET 0, `containerType$m 属性 ~SET `window^l, `containerName$m 属性 ~SET 空~文字列, `containerSrc$m 属性 ~SET 空~文字列, 【`containerId$m 属性 ~SET 空~文字列?】
注記: この~APIの将来~版では, `name$m 属性~用に他の値も追加することになるが、 今の所は一種類の値しかとり得ない。
◎ and set its attributes as follows: • Set attribution’s name attribute to "unknown". • NOTE: future iterations of this API will add more values to the name attribute of a TaskAttributionTiming object, but for now it can only be a single value. • Set attribution’s entryType attribute to "taskattribution". • Set attribution’s startTime and duration to 0. • Set attribution’s containerType attribute to "window". • Set attribution’s containerName and containerSrc attributes to the empty string. -
~IF[ %元凶~設定群 ~NEQ ~NULL ]: ◎ If culpritSettings is not null:
- %元凶~閲覧~文脈 ~LET %元凶~設定群 の`大域~obj$enVに`対応する閲覧~文脈$ ◎ Let culpritBC be culpritSettings’s global object's browsing context.
- ~Assert: %元凶~閲覧~文脈 ~NEQ ~NULL ◎ Assert: culpritBC is not null.
- %容器 ~LET %元凶~閲覧~文脈 の`容器$bc ◎ Let container be culpritBC’s browsing context container.
- ~Assert: %容器 ~NEQ ~NULL ◎ Assert: container is not null.
- %帰属 の `containerId$m 属性 ~SET [ %容器 の`~ID$ ~NEQ ε ならば それ / ~ELSE_ 空~文字列 ] ◎ Set attribution’s containerId attribute to the value of container’s ID, or the empty string if the ID is unset.
-
この段の目的においては、 所与の名前 %foo に対する “%foo 内容~属性~値” という表記は,次の略記である ⇒# %容器 は %foo 内容~属性を有するならば その値 / ~ELSE_ 空~文字列 ◎ ↓
%容器 に応じて: ◎ ↓
- `iframe$e 要素 ◎ If container is an iframe element:
- %帰属 の ⇒# `containerType$m 属性 ~SET `iframe^l, `containerName$m 属性 ~SET `name$a 内容~属性~値, `containerSrc$m 属性 ~SET `src$a 内容~属性~値 ◎ • Set attribution’s containerType attribute to "iframe". • Set attribution’s containerName attribute to the value of container’s name content attribute, or the empty string if the attribute is absent. • Set attribution’s containerSrc attribute to the value of container’s src content attribute, or the empty string if the attribute is absent.
- 注記: ここで~frameの現在の~URLではなく, `src$a 属性を記録するのは、 意図的である — これは,首に~frameを識別し易くすることが意味されていることに加え、 非同一-生成元~iframeの現在の~URLの発見を許容することは,~security問題になるので。 ◎ NOTE: it is intentional that we record the frame’s src attribute here, and not its current URL, as this is meant primarily to help identify frames, and allowing discovery of the current URL of a cross-origin iframe is a security problem.
- `frame$e 要素 ◎ If container is a frame element:
- %帰属 の ⇒# `containerType$m 属性 ~SET `frame^l, `containerName$m 属性 ~SET `name^a 内容~属性~値, `containerSrc$m 属性 ~SET `src^a 内容~属性~値 ◎ • Set attribution’s containerType attribute to "frame". • Set attribution’s containerName attribute to the value of container’s name content attribute, or the empty string if the attribute is absent. • Set attribution’s containerSrc attribute to the value of container’s src content attribute, or the empty string if the attribute is absent.
- `object$e 要素 ◎ If container is an object element:
- %帰属 の ⇒# `containerType$m 属性 ~SET `object^l, `containerName$m 属性 ~SET `~nameO$a 内容~属性~値, `containerSrc$m 属性 ~SET `data$a 内容~属性~値, ◎ • Set attribution’s containerType attribute to "object". • Set attribution’s containerName attribute to the value of container’s name content attribute, or the empty string if the attribute is absent. • Set attribution’s containerSrc attribute to the value of container’s data content attribute, or the empty string if the attribute is absent.
- `embed$e 要素 ◎ If container is an embed element:
- %帰属 の ⇒# `containerType$m 属性 ~SET `embed^l, `containerName$m 属性 ~SET 空~文字列, `containerSrc$m 属性 ~SET `~srcE$a 内容~属性~値 ◎ • Set attribution’s containerType attribute to "embed". • Set attribution’s containerName attribute to the empty string. • Set attribution’s containerSrc attribute to the value of container’s src content attribute, or the empty string if the attribute is absent.
- %開始 ~SET `時刻を粗化する$( %開始~時刻, %非同一-生成元~能力は隔離されるか ) ◎ ↓
- %終了 ~SET `時刻を粗化する$( %終了~時刻, %非同一-生成元~能力は隔離されるか ) ◎ ↓
- %新たな~entry ~LET %行先~realm 内の新たな `PerformanceLongTaskTiming$I ~obj ◎ Create a new PerformanceLongTaskTiming object newEntry with destinationRealm\
-
%新たな~entry の ⇒# `name$m 属性 ~SET %名前, `entryType$m 属性 ~SET `longtask^l, `startTime$m 属性 ~SET %開始, `duration$m 属性 ~SET [ %終了 ~MINUS %開始 ]の整数~部, `attribution$m 属性 ~SET `凍結d配列を作成する$( « %帰属 » )【!不要:If attribution is not null,】 ◎ and set its attributes as follows: • Set newEntry’s name attribute to name. • Set newEntry’s entryType attribute to "longtask". • Set newEntry’s startTime attribute to the result of coarsening start time given crossOriginIsolatedCapability. • Let dur be the result of coarsening end time given crossOriginIsolatedCapability, minus newEntry’s startTime. • Set newEntry’s duration attribute to the integer part of dur. • If attribution is not null, set newEntry’s attribution attribute to a new frozen array containing the single value attribution.
注記: この~APIの将来~版では, `attribution$m 属性に他の値も追加することになるが、 今の所は 1 個の値しか包含しない。 ◎ NOTE: future iterations of this API will add more values to the attribution attribute, but for now it only contains a single value.
- `処理能~entryを~queueする$( %新たな~entry ) ◎ Queue the PerformanceEntry newEntry.
5. ~securityと~privacyの考慮点
長い~task用の~APIは、[ 長い~taskの~sourceについて,生成元~安全な帰属~情報を含める ]ことにより,同一-生成元~施策を固守する。 また、 長い~task用には閾値 50ms がある。 所要時間は 1ms までの粒度で供される。 これらは組みで、 非同一-生成元への漏洩-に抗する必要十分な保護を供する。 【閾値 50ms は、~security用に導入されたものではないが,それでも。】 ◎ Long Tasks API adheres to the same-origin policy by including origin-safe attribution information about the source of the long task. There is a 50ms threshold for long tasks. Durations are only provided in 1 ms granularity. Together this provides adequate protection against cross-origin leaks.
この~APIは、[ 利用者により実行される~taskの所要時間と種別についての計時~情報 ]および[ 関数~callを生じさせた閲覧~文脈などの`帰属$ ]を供する。 これは、 攻撃者が~side-channel計時~攻撃を遂行して,[ 利用者の動作を推測する/利用者を識別する ]ことも可能化し得る。 例えば,長い~scriptに後続して長い具現化を併せる~patternで、 利用者による~social~widgetとのヤリトリを推測することもできる。 詳細な[ 関数~callの`帰属$ ]は、 利用者の動作を決定するために利用されることになろう。 ◎ The Long Tasks API provides timing information about the duration and type of tasks executed by the user, as well as attribution such as the browsing context causing the function calls. This could enable an attacker to perform side-channel timing attacks to guess the user’s action, or identify the user. For example, a pattern of long script followed by a long render could be put together to guess user’s interaction with a social widget. Detailed function call attribution would be used to determine the user’s action.
この~APIは、 新たな~privacy攻撃は導入しないが,既存の~privacy攻撃を速くすることもできる。 そのための軽減策はアリであり、 必要に応じて実装できる: ◎ While the API doesn’t introduce any new privacy attacks, it could make existing privacy attacks faster. Mitigations for this are possible and can be implemented as needed:
- ~APIが供する長い~taskの所要時間に対し,更に、 それを~~丸めたり~randomな揺らぎを追加して,攻撃から悪用され難くする。 ◎ Further clamp or add random jitter to the long task duration provided by the API to make attacks harder to exploit.
- 長い~taskを~APIに公開する生成元の個数を制限して、 それを超える~taskの帰属をぼやかす。 一例として,~pageに 5 個の~iframeが伴われる場合、 それらの~iframeのうち 3 個からは ~taskの帰属を受信して,他の 2 個からは~taskの帰属を受信しないようにする ( 【`PerformanceLongTaskTiming$I の】 `name$m を `unknown$l に設定する) こともできる。 ◎ Limit the number of origins for which longtasks are exposed by the API, and obfuscate the attribution of any tasks afterwards. For instance, a page with 5 iframes could receive only attribution for tasks from 3 of those iframes, and would receive no attribution (name set to unknown") for tasks from the other 2.
- 一定の閾値の後には、[ 元凶/帰属 ]情報を落とすことも許容する。 一例として,長い~taskが 10 個を超えて以降は、 どの~entryも,帰属を受信することなく それらの `name$m を `unknown$l にする。 ◎ Allow dropping the culprit/attribution information after a certain threshold. For instance, after 10 longtasks all entries would receive no attribution and their name would be "unknown".
- 公開される計時~情報に組込みの遅延を追加して、 長い~taskの分量に依存している攻撃を実行し難くする。 ◎ Add a built-in delay to the timing information exposed to make attacks dependent on longtask volume harder to execute.
5.1. 何が観測器に公開されるのか?
~top-level~pageの中にある すべての観測器 (すなわち,~pageと~main~frame内のすべての~iframe) は、 長い~taskが在ることについて通知を受信することになる。 それは、 当の~taskの[ 開始~時刻, 所要時間, 元凶~frameへの~pointer ]を公開する (所要時間は粒度 1ms で)。 この情報は、 今日においてすでに, `setTimeout()^m を利用して より高-分解能に観測できる 【それは、閾値 50ms により制限されない】 。 攻撃者は、[ ~page上のすべてを~clearしてから,非同一-生成元に属する脆弱な資源を追加することで、 `setTimeout()^m からの遅延が,その資源により生じることを確保する ]ことにより,これを行える。 【元凶とは】異なる~page(~UItabや~UIwindow)内の観測器は、 ~UAの~architectureを問わず,通知【において`帰属$】を受信するベキでない。 ◎ All observers within the top level page (i.e. all iframes in the page and the main frame) will receive notifications about presence of long tasks. We expose the start time of the task, its duration (with 1 ms granularity), and a pointer to the culprit frame. This information can already be observed today, and with higher resolution, using setTimeout. An attacker can do this by clearing everything else on the page and adding the vulnerable cross-origin resource to ensure that delays from the setTimeout are caused by that resource. Observers in other different pages (tabs or windows) should not receive notifications, regardless of the architecture of the user agent.
非同一-生成元に何が公開されるかに関する規則: ◎ Cross origin rules for what is exposed:
- 非同一-生成元に属する観測器は、 元凶が在る方向を知り得る — 例: 当の元凶は深く入子にされた~iframeである場合、 それを~hostしている~pageは,自身と元凶の合間にある最初の非同一-生成元を知れる。 ◎ Cross-origin observers may see the direction of the culprit e.g if the culprit is a deeply nested iframe, then the host page can see the first cross-origin between itself and the culprit.
- 逆に,元凶の方が~top-level~pageである場合、 深く埋込まれた~iframeは,[ 非同一-生成元に属する先祖~内で,ある長い~taskが生じたこと ]を知れるが,それについての情報は受信しない。 ◎ Conversely, if the culprit is the top level page, then a deeply embedded iframe can see that a longtask occurrred in its cross-origin ancestor but does not receive any information about it.
5.2. 考慮される攻撃~局面
考慮される計時~攻撃として,次が挙げられる: ◎ The following are the timing attacks considered:
- 伝統的な計時~攻撃 ⇒ 外部~資源の読込nにかかる時間を利用して,私的~dataの~sizeを露呈する。 一例として、 ある展示における隠された絵図の個数, ~usernameは妥当かどうか, 等々。 `例@http://crypto.stanford.edu/%7edabo/papers/webtiming.pdf$ を見よ。 ◎ Traditional timing attacks: using external resource load time to reveal the size of private data. For instance the number of hidden pictures in a gallery, whether username is valid, etc. See an example.
- ~side-channel計時~攻撃 ⇒ [ 動画~構文解析/ ~script構文解析/ ~app~cache読取n【この特能は~HTMLから廃された】/ `Cache$I ~API(~sw) ]の利用度に関する時間を利用して、 利用者を一意に識別するか, 利用者の[ 年齢, 性別, 所在, 関心事, 等々 ]が成す~profileを作成する。 `一例として@https://tom.vg/papers/timing-attacks_ccs2015.pdf$, ~social~network内の ある~permalink用の~pageからの状態s更新は、 一定の対象層(例: 20 代の女性)に制限-【するように公開-】され得る。 その~permalink~pageの~file~sizeは、 利用者は当の対象層に属するかどうか決定するために利用され得る。 【対象層に属さないならば、当の~pageを読込まないので,時間がかからない。】 ◎ Side-channel timing attacks: using time for video parsing, script parsing, App Cache reads or Cache API (service workers) usage to uniquely identify a user, or to create a profile of the user’s age, gender, location, and interests etc. For instance, status updates from a social network can be limited to certain demographic (eg. females of age 20-30) the file size of the permalink page can be used to determine whether the user is in the target demographic.
これらの局面は、[ 50ms 閾値, 非同一-生成元に関する境界 ]の組みで取組まれる。 すなわち、 信用されない非同一-生成元に属する観測器には,~taskの種別や追加的な帰属は示されない。 ◎ These scenarios are addressed by the 50ms threshold AND respecting cross-origin boundary i.e. not showing task type or additional attribution to untrusted cross origin observers.