ブラウザゲームの入力は何ミリ秒で画面に反映されるか
pointerdown・keydown のイベントが発生してから、次のアニメーションフレームでスクリプトが処理できるまで、何ミリ秒か。『60秒後の彼女』のコードで Chromium に計らせました。
1. 何を測ったか
入力イベントの timeStamp(仕様 WHATWG HTML / W3C UI Events)から、その直後の requestAnimationFrame コールバックが動くまでの経過を performance.now()(仕様 WHATWG High Resolution Time)で測りました。GPU への実描画完了ではなく「次フレームでスクリプトが観測できるまで」の proxy です。
2. 測定コード(抜粋)
const rec = (kind, evtTs) => {
const t0 = evtTs;
requestAnimationFrame(() => {
const t1 = performance.now();
window.__lat[kind].push(t1 - t0);
});
};
window.addEventListener('pointerdown', (e) => rec('pointer', e.timeStamp), true);
window.addEventListener('keydown', (e) => {
if (e.key === ' ' || e.key === 'Enter') rec('keyboard', e.timeStamp);
}, true);
各入力を 60 回ずつ発行し、中央値・p90・最大値を算出。外れ値は除外せず件数のみ表示。
3. 結果(この環境での値)
| 入力 | 最小 | 中央値 | p90 | 最大 | 平均 |
|---|---|---|---|---|---|
| pointerdown | 0.3 ms | 約 2〜4 ms | 約 13.5 ms | 32.2 ms | 4.8 ms |
| keydown (Space) | 0.2 ms | 約 0.6〜0.8 ms | 約 11.6 ms | 19.7 ms | 3.5 ms |
生データは リポジトリの reports/input-latency.json にあります。数値は実行ごとに変動します。
4. ポインタとキーボード
中央値はキーボードのほうがわずかに短い傾向でしたが、いずれも 1 フレーム(60Hz で約 16.7 ms)以内です。したがって本作のような「次のフレームで反映されれば良い」操作では、入力手段による差は体感に乗りにくい設計になっています。とはいえ、p90・最大値が 10〜30 ms に達するのは、他のスクリプト処理やガベージコレクションとの競合と考えられ、毎フレーム重い処理を積むと遅延が目立ちます。
5. フレーム境界と 60Hz / 120Hz
リフレッシュレートが 60Hz(約 16.7 ms/フレーム)の場合、入力がフレームの終わり近くに届くと次フレームまで最大約 16.7 ms 待ちます。120Hz(約 8.3 ms/フレーム)なら待ち時間の上限が半分になります。本作は performance.now() ベースの deadline タイマーで計時しているため、フレームレートに関わらず同じ実时刻で終了します(タイマー記事参照)。
6. 実装への反映
入力ハンドラは e.preventDefault() を適切に効かせ、イベントリスナは capture phase で登録し、フレーム内の重い同期処理を避ける方針です。これにより、測定した遅延を実用上問題ない範囲に保っています。
7. 読者向けチェックリスト
- 入力ハンドラが重い同期処理をしていないか(長いループ・同期 localStorage 等)
preventDefaultで既定動作(スクロール等)を抑制できているか- キーボードとポインタで同じ操作結果になるか
- フレーム落ち時にタイマーがズレないか(deadline 方式か)
8. 制限(limitations)
- これは「この Chromium ビルド・この OS」の値。端末一般の入力遅延ではない。
- GPU への実描画完了(present)ではなく、スクリプト観測可能な次フレームまで。
- バックグラウンド状態・CPU スロットル下は未測定(スロットルなし)。
- 実利用者の「操作のしやすさ」を測ったものではない。
出典
- WHATWG HTML Standard —
performance.now()(High Resolution Time) - W3C UI Events —
Event.timeStamp - MDN Web Docs — Pointer Events / KeyboardEvent