【この訳に固有の表記規約】
- この訳の~algoや定義の記述に利用されている各種記号( ~LET, 此れ, ~IF, ~THROW 等々)の意味や定義の詳細は、~SYMBOL_DEF_REFを~~参照されたし。
- 原文にて W3C [ `HTML$r / `WORKERS$r ]仕様による定義を参照している用語は、便宜のため,この訳では WHATWG HTML 仕様(の和訳)による定義を参照している。
- `外的な時計~調整@ — この訳では、原文の “system clock adjustments”, “system clock skew” の総称として,この語を用いることにする。 原文には説明されていないが、前者の system clock adjustments は、 NTP などの外部の時計と~system時計とのずれを — 自動的に,場合によっては利用者が — 補正することを指すようだ。 後者の clock skew は、 Wikipedia によれば[ 熱などの物理的な/回路構成などの機械的な ]要因による,~system内の複数箇所の間の同期のずれを意味するようだが、この語の用いられ方から,それに対処するために~system時計を補正することを指すようだ。
1. 序論
~INFORMATIVEECMAScript 言語~仕様 `ECMA-262$r は、 1970 年 1 月 1 日 UTC からの~milli秒~単位による時間を表現する時刻~値として, `Date^c ~objを定義する。 この値は, 1970 年 1 月 1 日 UTC から約 28 万 5616 年間のどの時刻も~milli秒~単位で表現でき、ほとんどの目的においては,この定義で足りる。 `DOMTimeStamp$I `WEBIDL$r も同様に定義されている。 ◎ The ECMAScript Language specification [ECMA-262] defines the Date object as a time value representing time in milliseconds since 01 January, 1970 UTC. For most purposes, this definition of time is sufficient as these values represent time to millisecond precision for any instant that is within approximately 285,616 years from 01 January, 1970 UTC. The DOMTimeStamp is defined similarly [WEBIDL].
これらの定義による時刻は、実施においては,`外的な時計~調整$の対象にもなる。 時刻~値は常に単調増加するとは限らず,後続の値は減少したり, 同じままになることもある。 ◎ In practice, these definitions of time are subject to both clock skew and adjustment of the system clock. The value of time may not always be monotonically increasing and subsequent values may either decrease or remain the same.
例えば 次の~scriptは、 %duration の計算結果として[ 正の値, 負の値, 0 ]いずれも記録し得る。 ◎ For example, the following script may record a positive number, negative number, or zero for computed duration: ◎ Example 1
var %mark_start = Date.now();
doTask(); // 何らかの~task
var %duration = Date.now() - %mark_start;
この定義による時刻は、~milli秒より細かい分解能はなく, `外的な時計~調整$の対象にもなるので、ある種の~taskには不足する。 例えば: ◎ For certain tasks this definition of time may not be sufficient as it does not allow for sub-millisecond resolution and is subject to system clock skew. For example,
- 文書~navi, 資源の~fetching, ~scriptの実行 などに費やされた時間を正確に計測しようと試みるとき、~milli秒より細かい分解能, かつ単調増加する時計が欲される。 ◎ When attempting to accurately measure the elapsed time of navigating to a Document, fetching of resources or execution of script, a monotonically increasing clock with sub-millisecond resolution is desired.
- ~scriptから~animationの状態を計算するとき、~animationを次の場面へ適正に更新するためには,開発者は ~animationに費やされた時間の長さを正確に知る必要がある。 ◎ When calculating the animation state from script, developers will need to accurately know the amount of time that has elapsed in the animation in order to properly update the next scene of the animation.
- ~scriptに基づく~animationの~frame~rateを計算するとき、~animationが 60 FPS で描画されているかどうか決定するためには,~milli秒より細かい分解能が必要になる。 ~milli秒より細かくなければ、開発者は 58.8 FPS と 62.5 FPS を区別するのが限界になる。 【1 ~frameあたり前者が 1/58.8 = 約 0.017 秒, 後者は 0.016 秒で,その差 1/1000 秒】 ◎ When calculating the frame rate of a script based animation, developers will need sub-millisecond resolution in order to determine if an animation is drawing at 60 FPS. Without sub-millisecond resolution, a developer can only determine if an animation is drawing at 58.8 FPS or 62.5 FPS.
- ~animation内の特定の時点に音声を~cueしようと試みるときや, 音声と~animationの同期を確保するためには、開発者は,~animationと音声に費やされる時間の長さを正確に知る必要がある。 ◎ When attempting to cue audio to a specific point in an animation or ensure that the audio is synchronized with the animation, developers will need to accurately know the amount of time elapsed in the animation and audio.
- 複数の文脈~下の作業を,~milli秒より細かい分解能で互いに同期させる必要があるとき(例: `専用~worker$ / `共用~worker$ を用いて,~renderer文脈~下で~animation, 音声, 等々を駆動する)や、複数の文脈で生じた~eventたちが成す時列線の,統一された~viewを作成する必要があるとき。 ◎ When multiple contexts need to synchronize work with sub-millisecond resolution (e.g. when using dedicated or shared workers to drive animation, audio, etc., in a renderer context), or to create a unified view of the event timeline.
この仕様は、 `Date.now()^c `ECMA-262$r の挙動を変更するよう提案するものではない。 それは、暦における現在の時刻~値を決定する点においては純粋に有用であり,長い利用の歴史がある。 `DOMHighResTimeStamp$I 型と `Performance$I ~interfaceの[ `now()$m ~method/ `timeOrigin$m 属性 ]が、[ 単調増加する, ~milli秒より細かい分解能による時刻~値 ]を供することにより,上に挙げた課題を解決する。 ◎ This specification does not propose changing the behavior of Date.now() [ECMA-262] as it is genuinely useful in determining the current value of the calendar time and has a long history of usage. The DOMHighResTimeStamp type, performance.now method, and performance.timeOrigin attributes of the Performance interface resolve above issues by providing monotonically increasing time values with sub-millisecond resolution.
1.1. 例
~INFORMATIVE開発者は、自身の~app全体にわたり,`時刻起点$が異なる[ `専用~worker$/`共用~worker$ ]からの~eventも含むような時列線†を構築したいと望むこともあろう。 `timeOrigin$m 属性の助けを借りて 各~eventの `DOMHighResTimeStamp$I 値を換算すれば、~appは,そのような~eventたちを同じ時列線~上に表示できる。 ◎ A developer may wish to construct a timeline of their entire application, including events from dedicated or shared workers, which have different time origin's. To display such events on the same timeline, the application can translate the DOMHighResTimeStamp's with the help of the performance.timeOrigin attribute.
【† 時列線( timeline ): 生じた~eventをその時刻とともに時系列順に記録するもの(無数の時刻~値からなる昇順の並びが成す線)。 】
// ---- worker.js ----------------------------- /* 共用~worker内の~script ◎ Shared worker script */ onconnect = function(%e) { var %port = %e.ports[0]; %port.onmessage = function(%e) { /* ~worker内での計時~task ◎ Time execution in worker */ var %task_start = performance.now(); %result = runSomeWorkerTask(); var %task_end = performance.now(); } /* 結果と, および~epochに相対的な時刻印を,別の文脈へ送信する ◎ Send results and epoch-relative timestamps to another context */ %port.postMessage({ 'task': 'Some worker task', 'start_time': %task_start + performance.timeOrigin, 'end_time': %task_end + performance.timeOrigin, 'result': %result }); } // ---- application.js ------------------------ /* 文書~内での計時~task ◎ Timing tasks in the document */ var %task_start = performance.now(); runSomeApplicationTask(); var %task_end = performance.now(); /* 実行時の処理能~dataを~uploadするために開発者が供した~method ◎ developer provided method to upload runtime performance data */ reportEventToAnalytics({ 'task': 'Some document task', 'start_time': %task_start, 'duration': %task_end - %task_start }); /* ~workerの時刻印を文書の`時刻起点$に換算する ◎ Translating worker timestamps into document's time origin */ var %worker = new SharedWorker('worker.js'); %worker.port.onmessage = function (%event) { var %msg = %event.data; /* ~epochに相対的な時刻印を文書の`時刻起点$に換算する ◎ translate epoch-relative timestamps into document's time origin */ %msg.start_time = %msg.start_time - performance.timeOrigin; %msg.end_time = %msg.end_time - performance.timeOrigin; reportEventToAnalytics(%msg); }
2. 適合性
【 この節の内容は W3C 日本語訳 共通ページ に委譲 】
3. 時刻起点
`時刻起点@ ( time origin )とは、時間を計測する起点であり,所与の`大域~obj$に応じて,次で定義される時点にされ~MUST: ◎ The time origin is the time value from which time is measured:
- `Window$I ~objである場合: ◎ If the global object is a Window object, the time origin MUST be equal to:
- 前の文書がない場合 ⇒ 最初に`閲覧文脈が作成され$た時点 ◎ the time when the browsing context is first created if there is no previous document;
- 他の場合,前の文書が存在し, それが`~unloadを~promptする$間に利用者に確認~dialogが表示された場合 ⇒ 利用者が~naviを確認した時点 ◎ otherwise, the time of the user confirming the navigation during the previous document's prompt to unload algorithm, if a previous document exists and if the confirmation dialog was displayed;
- 他の場合 ⇒ `Window$I ~objに`結付けられている文書$の読込みを担当する`~navi$を開始した時点 ◎ otherwise, the time of starting the navigation responsible for loading the Window object's newest Document object.
- `WorkerGlobalScope$I ~objである場合:
- ~workerの`公式的な作成時点$。 `WORKERS$r ◎ If the global object is a WorkerGlobalScope object, the time origin MUST be equal to the official moment of creation of the worker. [WORKERS]
- 他の場合:
- 未定義とする。 ◎ Otherwise, the time origin is undefined.
`時刻起点~時刻印@ は、`時刻起点$を指す 【大域的な】 時刻を与える,高分解能な時刻~値である。 所与の`大域~obj$ %G の`時刻起点~時刻印$は: ◎ The time origin timestamp is the high resolution time value at which time origin is zero. To obtain the time origin timestamp given a global object ( global): ◎ Assert that global's time origin is not undefined.
- %G の`時刻起点$が未定義の場合は定義されない。
-
他の場合、次の 2 つを加算した結果として定義される:
- `~Unix時間$による[ `大域的な単調増加~時計$が時刻 0 を指す時点 ]の時刻を,高分解能で表現している `DOMHighResTimeStamp$I 値 ◎ Let t1 be the DOMHighResTimeStamp representing the high resolution Unix time at which the global monotonic clock is zero.
- `大域的な単調増加~時計$による[ %G の`時刻起点$ ]の時刻を,高分解能で表現している `DOMHighResTimeStamp$I 値 ◎ Let t2 be the DOMHighResTimeStamp representing the high resolution time value of the global monotonic clock at global's time origin. ◎ Return the sum of t1 and t2.
注記: `時刻起点~時刻印$は、`外的な時計~調整$の対象でない`大域的な単調増加~時計$を基準に記録されるので,[ `Date.now()^c を “~zero時刻” 【すなわち、時刻起点】 に実行したときの結果と相違し得る。 単調増加~時計 節 を見よ。 ◎ Note ◎ The time origin timestamp and the value returned by Date.now() executed at "zero time" can differ because the former is recorded with respect to a global monotonic clock that is not subject to system and user clock adjustments, clock skew, and so on—see 7. Monotonic Clock.
`現在の高分解能~時刻@ は、`時刻起点$から現在時(概して, “今( now )” とも呼ばれる)までの時間~差を,高分解能で表す時刻~値である。 ◎ The current high resolution time is the high resolution time from the time origin to the present time (typically called "now").
4. `DOMHighResTimeStamp^I 型
`DOMHighResTimeStamp@I 型は、次のいずれかを表現する,~milli秒~単位による値を格納するために利用される:
- `時刻起点$から相対的に計測された時刻
- `大域的な単調増加~時計$から相対的に計測された時刻
- 2 つの `DOMHighResTimeStamp$I 値の時間~差
typedef double `DOMHighResTimeStamp$I;
`DOMHighResTimeStamp$I 値は、~milli秒~単位の時間を,[ 計測には十分, かつ計時~攻撃は防止する ]正確~さで表現するべきである。 追加の考慮点については、時計の分解能節を見よ。 ◎ A DOMHighResTimeStamp SHOULD represent a time in milliseconds accurate enough to allow measurement while preventing timing attack - see 8.1 Clock resolution for additional considerations.
注記: ~UAは、~hardwareまたは~softwareに因る拘束から, `DOMHighResTimeStamp$I 値による時間を~milli秒より細かい正確~さで供せない場合には、~milli秒の正確~さで表現できる。 ◎ Note ◎ If the User Agent is unable to provide a time value accurate to 5 microseconds due to hardware or software constraints, the User Agent can represent a DOMHighResTimeStamp as a time in milliseconds accurate to a millisecond.
5. `Performance^I ~interface
[`Exposed$=(Window,Worker)] interface `Performance@I : `EventTarget$I { `DOMHighResTimeStamp$I `now()$m; readonly attribute `DOMHighResTimeStamp$I `timeOrigin$m; [`Default$] object `toJSON()$m; };
- `now()@m
- 被呼出時には、`現在の高分解能~時刻$を返さ~MUST。 `basic.any$test `basic.any.worker$test ◎ The now() method MUST return the current high resolution time.
- `timeOrigin@m
- 取得子は、此れに`関連する大域~obj$用の`時刻起点~時刻印$を高分解能で表現する, `DOMHighResTimeStamp$I 値を返さ~MUST。 `timeOrigin$test `window-worker-timeOrigin.window$test ◎ The timeOrigin attribute MUST return a DOMHighResTimeStamp representing the high resolution time of the time origin timestamp for the relevant global object of the Performance object.
- `toJSON()@m
- 被呼出時には、 `WEBIDL$r による`既定の~toJSON演算$を走らす。 ◎ When toJSON is called, run [WEBIDL]'s default toJSON operation.
6. `performance^m 属性
`WindowOrWorkerGlobalScope$I 上の `performance@m 属性は、`大域~obj$からの[ 処理能に関係する属性や~method ]へ~accessできるようにする。 ◎ The performance attribute on the WindowOrWorkerGlobalScope allows access to performance related attributes and methods from the global object.
partial interface mixin `WindowOrWorkerGlobalScope$I { [`Replaceable$] readonly attribute `Performance$I `performance$m; };
7. 単調増加~時計
[ 同じ`時刻起点$を共有する,各 `Performance$I ~obj ]の `now()$m ~methodが返す時刻~値は、同じ`単調増加~時計$を利用し~MUST。 同じ `Performance$I ~objの `now()$m ~methodが返す,時系列順に記録された 2 つの時刻~値の差は、決して負になっては~MUST_NOT。
`単調増加~時計@ とは、`外的な時計~調整$の対象にされることなく,単調増加するような時計である。 `monotonic-clock.any$test `monotonic-clock.any.worker$test
【 どの `Performance$I ~objたちが同じ`時刻起点$を共有するものとされるかは、ここには述べられていない。 】
◎ The time values returned when calling the performance.now() method on Performance objects with the same time origin MUST use the same monotonic clock that is monotonically increasing and not subject to system clock adjustments or system clock skew. The difference between any two chronologically recorded time values returned from the performance.now() method MUST never be negative if the two time values have the same time origin.`timeOrigin$m が返す時刻~値には、同じ`大域的な単調増加~時計$が利用され~MUST†。 `大域的な単調増加~時計@ とは、`~Unix時間$を基準にするような`単調増加~時計$であり,いくつかの`時刻起点$から共有される。 ~privacyと保安 を見よ。 `test_cross_frame_start$test
【 どの`時刻起点$ — 言い換えれば、`大域~obj$ — たちが同じこの時計を共有するものとされるかは,ここには規定されていないが、下の注記に見られるように,互いに情報をやりとりできる`大域~obj$どうしは共有することになるであろう。 】【† この要件をより詳細に述べるなら、 “2 つの`大域~obj$ %G1, %G2 が同じ`大域的な単調増加~時計$を共有するならば、 %G1, %G2 の `performance$m 属性が返す `Performance$I ~objの `timeOrigin$m が返す時刻~値には,その時計が利用され~MUST” となるであろう。 】
◎ The time values returned when getting performance.timeOrigin MUST use the same global monotonic clock that is shared by time origin's, is monotonically increasing and not subject to system clock adjustments or system clock skew, and whose reference point is the Unix time—see 8. Privacy and Security.注記: ~UAは、[ ~browserの各~再起動 / 他から隔離された閲覧~session(例: incognito 【private】 または それに類する閲覧~mode)の各~開始 ]ごとに,自身の`大域的な単調増加~時計$を再設定できる。 そのため,開発者は、[[ 過去現在未来すべての文脈にわたり,単調増加するような~prop ]を保持する,絶対的な時刻 ]には,大域的な時刻印を利用するべきでない。 実施において,単調増加する~propを適用できる用途は、[ 供されている~messagingの仕組み — 例: `postMessage()^m, `BroadcastChannel$I, 等々 — を介して~messageを交換することにより,他へ到達できるような文脈 ]に限られる。 ◎ Note ◎ The user agent can reset its global monotonic clock across browser restarts, or whenever starting an isolated browsing session—e.g. incognito or similar browsing mode. As a result, developers should not use global timestamps as absolute time that holds its monotonic properties across all past, present, and future contexts; in practice, the monotonic properties only apply for contexts that can reach other by exchanging messages via one of the provided messaging mechanisms - e.g. postMessage, BroadcastChannel, etc.
8. ~privacyと保安
8.1. 時計の分解能
正確な計時~情報への~accessは、計測と~scheduling 両~目的において,多くの~appに共通する要件である。 例えば, ~animation, 音, その他の~page上の活動を協調させ,より良い利用者~体験を供するためには、高分解能な時間への~accessを要する。 同様に,計測により、開発者は,~codeの決定的な部位における処理能を追跡したり, 退歩を検出する, 等々 が可能になる。 ◎ Access to accurate timing information, both for measurement and scheduling purposes, is a common requirement for many applications. For example, coordinating animations, sound, and other activity on the page requires access to high-resolution time to provide a good user experience. Similarly, measurement enables developers to track the performance of critical code components, detect regressions, and so on.
しかしながら,その同じ正確な計時~情報への~accessは、さもなければ攻撃者が見たり~accessできない~dataを推測可能にするような,悪意的な攻撃~目的にも利用され得る。 例えば~cache攻撃と統計的~指紋収集( statistical fingerprinting )は、悪意的な~websiteが,[ ~browserや~appから起動される様々な演算による,高分解能な計時~data ]を[ 利用者たちを分別したり, 場合によっては特定0の利用者を識別する ]ために利用し得るときの、~privacyと保安~上の懸念である — `CACHE-ATTACKS$r を見よ。 ◎ However, access to the same accurate timing information can sometimes be also used for malicious purposes by an attacker to guess and infer data that they can't see or access otherwise. For example, cache attacks and statistical fingerprinting is a privacy and security concern where a malicious web site may use high resolution timing data of various browser or application-initiated operations to differentiate between subset of users, and in some cases identify a particular user - see [CACHE-ATTACKS].
この仕様は、これまで `DOMTimeStamp$I に公開され可用であった~milli秒の分解能より正確な,より細かい時間~分解能を供する~APIを定義する。 しかしながら,この新たな~APIがなくとも、攻撃者は,~~反復~実行と統計的~解析を通して,高分解能の見積もりを得ることはできる。 新たな~APIにより,そのような攻撃の正確さや速度が有意に向上されないことを確保するため、 `DOMHighResTimeStamp$I 型の分解能は,攻撃を防止するに十分な~~精度に止めることが推奨される。 `timing-attack$test ◎ This specification defines an API that provides sub-millisecond time resolution, which is more accurate than the previously available millisecond resolution exposed by DOMTimeStamp. However, even without this new API an attacker may be able to obtain high-resolution estimates through repeat execution and statistical analysis. To ensure that the new API does not significantly improve the accuracy or speed of such attacks, the recommended minimum resolution of the DOMHighResTimeStamp type should be inaccurate enough to prevent attacks.
そのような計時側からの攻撃を まるごと軽減するような実施は、可能でない: そのためには、すべての演算の実行~時間は,機密的~情報の値に応じて変わらないようにするか、~appを,時間に関係するあらゆる~~基盤(時計, ~timer, ~counter, 等々)から隔離する必要があるが、いずれも ~browserと~app開発者に関わる複雑さや,処理能への負の効果, ~appの応答性に関わるものであり、実用的でない。 ◎ Mitigating such timing side-channel attacks entirely is practically not possible: either all operations would have to execute in a time that does not vary based on the value of any confidential information, or, the application would need to be isolated from any time-related primitives (clock, timers, counters, etc). Neither is practical due to the associated complexity for the browser and application developers and the associated negative effects on performance and responsiveness of applications.
8.2. 時計の~drift
この仕様は、[ ~milli秒より細かい分解能による`時刻起点~時刻印$ ]を供する~APIも定義する。 ~APIには[ すべての~browser文脈にわたって共有され~MUST,`大域的な単調増加~時計$ ]が要求され,それを~appに公開する。 この時計は,物理的な時刻に縛られる必要はないが、新たな[ 利用者についての指紋収集- ]~entropyを公開するのを避けるため,`~Unix時間$を基準に設定することが推奨される。 ~Unix時間は,すでに~appにより容易に得られる一方で、新たな論理的~時計を公開するのは,新たな情報を供するに等しいので。 ◎ This specification also defines an API that provides sub-millisecond time resolution of the zero time of the time origin, which requires and exposes a global monotonic clock to the application, and that must be shared across all the browser contexts. The global monotonic clock does not need to be tied to physical time, but is recommended to be set with respect to the Unix time to avoid exposing new fingerprint entropy about the user—e.g. this time can already be easily obtained by the application, whereas exposing a new logical clock provides new information.
しかしながら,上述した仕組みの下でも、`大域的な単調増加~時計$は, 時計の~drift ( clock drift, “遅れ/進み” )に関する分解能も供し得る。 今日の~appは、同じ文脈の中の複数の時点で,[ 従来の時計による時刻印, 単調増加~時計による時刻印 ]を(順に, `Date.now()^c, `performance.now()$m を介して)得て,それらの間の~drift — 例えば`外的な時計~調整$に因るそれ — を観測できる。 攻撃者はまた、[ `大域的な単調増加~時計$から報告される`時刻起点~時刻印$ ]を `timeOrigin$m 属性から得た上で、それと,現在の[ 従来の時計により,`大域的な単調増加~時計$が 0 を指すと見積もられる時点(すなわち ( `Date.now()^c − `performance.now()$m ) ) ]の時刻とを,長時間にわたり比較して、これらの時計どうしの時計の~driftを観測できる可能性がある。 ◎ However, even with above mechanism in place, the global monotonic clock may provide additional clock drift resolution. Today, the application can timestamp the time-of-day and monotonic time values (via Date.now() and performance.now()) at multiple points within the same context and observe drift between them—e.g. due to automatic or user clock adjustments. With the performance.timeOrigin attribute, the attacker can also compare the time at which time origin is zero, as reported by the global monotonic clock, against the current time-of-day estimate of when it is zero (i.e. difference between Date.now()-performance.now() and performance.timeOrigin) and potentially observe clock drift between these clocks over a longer time period.
【 例えば暗号処理を考える。 その処理の重さ(計算量)に因る CPU 熱は、`外的な時計~調整$(この事例では clock skew )をもたらす結果,時計の~driftに反映され得る。 攻撃者は、いくつかの入力とその計算量との相関関係を解析して,ある程度の情報を推定できるかもしれない。 】
実施においては、~appは,同じ時刻~driftを複数回の~naviにわたり観測できる: ~appは、各~文脈における論理的な時刻を記録し, ~client/~server 時刻~同期の仕組みを利用して、利用者の時計における変化を推定できる。 同様に~TCP時刻印などの低層の仕組みは、複数回の訪問を要することなく,同じ高分解能な情報を~serverに露呈し得る。 そのようなわけで,この~APIにより供される情報は、有意な, あるいは以前までは可用でなかった,利用者についての~entropyを公開するべきでない。 ◎ In practice, the same time drift can be observed by an application across multiple navigations: the application can record logical time in each context and use a client or server time synchronization mechanism to infer changes in the user's clock. Similarly, lower-layer mechanisms such as TCP timestamps may reveal same high-resolution information to the server without the need for multiple visits. As such, the information provided by this API should not expose any significant or previously not available entropy about the user.