JavaScriptにおいて経過時間を扱う処理は、ストップウォッチ、ゲームの経過時間表示、APIレスポンスの計測など、多岐にわたる開発現場で求められます。
近年のWebアプリケーションでは、単に時間を測るだけでなく、ミリ秒単位の正確な計測や、ユーザーにとって見やすい形式でのリアルタイム表示が重要視されています。
本記事では、JavaScriptで経過時間を計測・表示するための基本から、2026年現在の開発標準となっている最新の手法までを体系的に紹介します。
初心者の方でも実装できるよう、具体的なサンプルコードを交えながら、用途に応じた最適なアプローチを解説していきます。
JavaScriptにおける時間計測の基本概念
JavaScriptで経過時間を計測する際の基本的な考え方は、ある処理を開始した「開始時刻」と、終了した「終了時刻」の差分を求めることにあります。
取得した差分はミリ秒単位の数値として得られるため、これを秒や分に変換して利用します。
古くから利用されてきたDateオブジェクトに加え、現在ではより高精度な計測が可能なPerformanceインターフェースが広く普及しています。
また、2026年現在はTemporal APIという新しい日付操作の標準仕様も検討・導入が進んでおり、時間計測の選択肢が広がっています。
まずは、プロジェクトの要件に合わせて「どの程度の精度が必要か」を正しく判断することが、実装の第一歩となります。
Dateオブジェクトを使用した手軽な経過時間計測
最も一般的で、かつ実装が容易な方法が、Dateオブジェクトを利用した計測です。
Date.now()メソッドを使用すると、1970年1月1日 00:00:00 UTCからの経過時間をミリ秒単位で取得できます。
Date.now()による実装例
以下のコードは、ある処理の開始前と開始後に時刻を取得し、その差分を表示するシンプルな例です。
// 計測開始
const startTime = Date.now();
// 疑似的な重い処理(例として1秒待機)
const doSomething = () => {
const end = Date.now() + 1000;
while (Date.now() < end) {
// ループによる待機
}
};
doSomething();
// 計測終了
const endTime = Date.now();
// 経過時間を計算(ミリ秒)
const elapsedTime = endTime - startTime;
console.log(`処理にかかった時間: ${elapsedTime}ミリ秒`);
処理にかかった時間: 1000ミリ秒
Dateオブジェクトを使用するメリットとデメリット
Date.now()の最大のメリットは、記述がシンプルで直感的である点にあります。
また、ほぼすべてのブラウザや実行環境で動作するため、互換性を気にする必要がありません。
一方で、デメリットとして「精度が1ミリ秒単位であること」や「システム時計の影響を受けること」が挙げられます。
ユーザーがOSの時計を手動で変更した場合や、NTPによる自動時刻同期が行われた際に、計測結果に誤差が生じる可能性があります。
そのため、厳密なパフォーマンス測定が必要な場面には向いておらず、簡易的なタイマー機能などに適した手法と言えます。
performance.now()による高精度な計測
アニメーションの制御や、プログラムの細かなボトルネック調査など、高い精度が求められる場合にはperformance.now()を使用します。
これは「ハイレゾリューション・タイムスタンプ」と呼ばれ、マイクロ秒(0.001ミリ秒)単位の精度を提供します。
なぜperformance.now()が優れているのか
performance.now()は、システム時計ではなく「ブラウザがページを読み込み始めてからの経過時間」を基準にしています。
そのため、OSの時刻変更などの外部要因に左右されないという特徴を持っています。
常に一定の速度で増加する数値(モノトニック・クロック)を返すため、信頼性の高い経過時間の算出が可能です。
// 高精度な計測開始
const startHighRes = performance.now();
// 計測対象の処理
for (let i = 0; i < 1000000; i++) {
// 何らかの計算処理
}
// 高精度な計測終了
const endHighRes = performance.now();
// 小数点まで含んだ経過時間が出力される
const duration = endHighRes - startHighRes;
console.log(`詳細な経過時間: ${duration.toFixed(4)}ミリ秒`);
詳細な経過時間: 1.2345ミリ秒
セキュリティ上の制限事項
なお、セキュリティ上の理由(Spectreなどのサイドチャネル攻撃への対策)から、現在の主要ブラウザではperformance.now()の解像度をあえて意図的に制限している場合があります。
具体的には、数マイクロ秒から数十マイクロ秒単位での丸め処理が行われることが一般的です。
それでもなお、通常のDate.now()に比べれば圧倒的に高い精度を保っています。
経過時間のフォーマットとUI表示
計測されたミリ秒単位の数値は、そのままではユーザーにとって理解しづらいものです。
「02:15.50」のような、見やすい形式へ変換する処理を実装してみましょう。
ミリ秒を「分:秒:ミリ秒」に変換する関数
以下のロジックは、取得したミリ秒から各単位を算出する方法を示しています。
function formatElapsedTime(ms) {
// 各単位の計算
const minutes = Math.floor(ms / 60000);
const seconds = Math.floor((ms % 60000) / 1000);
const milliseconds = Math.floor((ms % 1000) / 10);
// 0埋め処理(パディング)
const mStr = String(minutes).padStart(2, '0');
const sStr = String(seconds).padStart(2, '0');
const msStr = String(milliseconds).padStart(2, '0');
return `${mStr}:${sStr}.${msStr}`;
}
const exampleTime = 125500; // 125.5秒
console.log(formatElapsedTime(exampleTime));
02:05.50
リアルタイムに経過時間を更新する方法
経過時間を画面に表示し続ける場合、setIntervalを使用するのが一般的ですが、再描画のタイミングに合わせるならrequestAnimationFrameが理想的です。
ブラウザの描画リフレッシュレート(通常は秒間60回)に同期して処理を実行するため、より滑らかな表示が可能になります。
let start;
const displayElement = document.getElementById('timer');
function update(timestamp) {
if (!start) start = timestamp;
const elapsed = timestamp - start;
// 前述のフォーマット関数などを利用して表示
displayElement.textContent = formatElapsedTime(elapsed);
// 次のフレームでも実行
requestAnimationFrame(update);
}
// 計測開始ボタンなどで呼び出す
// requestAnimationFrame(update);
2026年の新標準:Temporal APIによる時間操作
モダンなJavaScript開発において注目されているのが、Temporal APIです。
従来のDateオブジェクトは、ミュータブル(可変)であることや、タイムゾーンの扱いが難しいといった多くの課題を抱えていました。
Temporal APIはこれらの問題を解決し、直感的で正確な時間操作を可能にします。
Temporal.Durationを使用した差分計算
Temporal APIでは、時間の「長さ」を表すTemporal.Durationオブジェクトが用意されています。
これを用いると、経過時間の計算や比較が極めてシンプルになります。
// 2026年時点でのTemporal APIの使用例(ポリフィルまたは対応環境が必要)
const t1 = Temporal.Now.instant();
// 何らかの処理...
const t2 = Temporal.Now.instant();
// 二つの時点の差分を取得
const duration = t2.since(t1);
console.log(`経過時間: ${duration.total({ unit: 'millisecond' })}ミリ秒`);
console.log(`フォーマット済み: ${duration.toString()}`);
Temporal APIを使用することで、これまで自前で書いていた「ミリ秒から分への計算」などのロジックをライブラリなしで安全に処理できるようになります。
2026年のプロジェクトであれば、将来性を考慮してTemporalの導入を検討する価値は十分にあります。
コンソールでの簡易的な計測:console.time
コードのデバッグ中に、特定の関数の実行速度を素早く知りたい場合は、console.time()とconsole.timeEnd()が非常に便利です。
これはコードの中に計測用のラベルを貼るだけで、ブラウザのコンソールに自動的に結果を出力してくれる仕組みです。
console.time('ループ処理の計測');
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
console.timeEnd('ループ処理の計測');
ループ処理の計測: 2.45ms
ラベル名を一致させるだけで複雑な計算が不要なため、開発中の一時的な調査には最も適した手法です。
計測手法の比較まとめ
これまで紹介した各手法の特徴を、用途別にまとめました。
| 手法 | 精度 | 主な用途 | 特徴 |
|---|---|---|---|
| Date.now() | 1ms | 一般的なタイマー | 実装が簡単。古いブラウザでも動作。 |
| performance.now() | μs単位 | パフォーマンス分析 | 高精度。システム時計の影響を受けない。 |
| Temporal API | ns単位 | 複雑な時間計算 | 2026年の新標準。安全で高機能。 |
| console.time() | ブラウザ依存 | デバッグ | コードが汚れず、手軽に計測可能。 |
まとめ
JavaScriptで経過時間を計測する方法は、進化を続けています。
まずは基本となるDate.now()で仕組みを理解し、より正確なデータが必要になった段階でperformance.now()へとステップアップするのが良いでしょう。
また、UIとして経過時間を表示する際には、ユーザーの利便性を考えたパディング処理や単位変換が欠かせません。
さらに、2026年以降のモダンな開発では、Temporal APIを活用することで、より堅牢なコードを書くことが可能になります。
用途に合わせた適切なAPIを選択し、正確でストレスのない時間計測機能を実装してください。
