高分解能な計時レベル2がWeb標準のリストに加わった。新しい標準は、以前の高分解能な計時レベル1標準を更新して置き換える。レベル2は、パフォーマンスモニタリング、アニメーション、オーディオキュー、およびブラウジングコンテキスト間の同期の信頼性と精度を強化する。
Web Performance Working Groupは、W3C勧告として高分解能な計時レベル2を公開している。この仕様では、時刻の起点と現在の時刻をミリ秒よりも細かい(sub-millisecond)分解能で提供するAPIを定義している。高分解能な計時レベル2は、高分解能な計時の最初のバージョンを置き換える。
レベル2の仕様は、エッジケースを修正し、新しいユースケースを可能にすることを目的としている。仕様には次のように記載されている:
時刻値[Date.now()で測定]は常に単調に増加するとは限らず、後続の値は減少するか、同じままになる場合があります。
[追加]特定のタスクでは、このミリ秒の定義は、ミリ秒より細かい(sub-millisecond)分解能を許可しないため、十分でない場合があります。
実際、次のスクリプトは、場合によっては期間の計算がゼロまたは負の数になる。
var mark_start = Date.now();
doTask(); // Some task
var duration = Date.now() - mark_start;
この直感的でない動作は、ECMAScript言語仕様(つまり、JavaScript)が1970年1月1日UTCからのミリ秒単位の時間を表す時刻値としてDate
オブジェクトを定義しているという事実から生じている。ミリ秒の精度は、doTask
関数が十分に速く実行された場合、測定された期間が0になる可能性があることを意味する。doTask
の実行中にシステムクロックを前後に調整すると、測定された期間が負になるか、非常に大きくなる可能性がある。これは、悪意のある努力だけで発生するわけではない。夏時間の変更により、測定値が歪む場合もある。
仕様では、ミリ秒未満の計時の分解能を必要とするいくつかの使用例を特定している。JavaScriptでアニメーションを作成する開発者は、次のことを行うために精度の向上が必要になる場合がある。アニメーションが60フレーム/秒で描画されているかどうかを判断する。アニメーションの特定のポイントにオーディオをキューイングするか、オーディオがアニメーションと同期していることを確認する。さらに、複数のコンテキストのワーカーは、より高い計時分解能を利用して、描画コンテキストでアニメーションやオーディオなどを同期して駆動したり、アプリケーション全体のイベントタイムラインの統合ビューを作成したりできる。
Date.now
APIは変更されていないが、レベル2仕様では、DOMHighResTimeStamp
タイプ、performance.now
メソッド、およびPerformance
インターフェイスにperformance.timeOrigin
属性が追加されている。新しいAPIは、ミリ秒より細かい(sub-millisecond)分解能で単調に増加する時刻値を提供する。
performance.now()
タイマーは相対的な測定値である。たとえば、ページが開かれたときやワーカーが作成されたときなど、実行コンテキストが生成されると0からカウントを開始する。したがって、実行コンテキスト間でperformance.now()
によって返された値を直接比較することは、共有された参照ポイントがないと不可能である。タイマーの初期化が発生したとき、performance.timeOrigin
はグローバルシステムクロックの値を返す。
Professional JavaScript for Web Developersの最近の版では、次の例を示している:
const relativeTimestamp = performance.now();
const absoluteTimestamp = performance.timeOrigin + relativeTimestamp;
console.log(relativeTimestamp);
// 244.43500000052154
console.log(absoluteTimestamp);
// 1561926208892.4001
レベル2の仕様では、より高い計時の分解能に関連するセキュリティリスクの警告が表示される:
キャッシュ攻撃、統計的フィンガープリント、マイクロアーキテクチャ攻撃はプライバシーとセキュリティの問題であり、悪意のあるWebサイトがさまざまなブラウザまたはアプリケーションが開始した操作の高分解能のタイミングデータを使用して、ユーザのサブセットを区別したり、特定のユーザーを識別したり、関連しない同一プロセスのユーザデータを明らかにできます。詳細については、CACHE-ATTACKSおよびSPECTREをご覧ください。
前述の攻撃に対抗するために、新しい仕様では5マイクロ秒以上の計時分解能を推奨している(したがって、1ミリ秒の500分の1)。すべての主要なブラウザは、それに応じてperformance.now()
の最大精度を低下させるか、タイムスタンプにランダム性を組込んでいる。
新しい標準は、ほとんどのブラウザにすでに実装されている。