入力遅延について学び、インタラクティビティを高速化するために遅延を短縮する手法を学びます。
ウェブ上のインタラクションは複雑なもので、ブラウザ内でさまざまなアクティビティが発生してインタラクションを促します。ただし、イベント コールバックが実行されるまでに入力遅延が発生するという点は、どの方法でも共通しています。このガイドでは、入力遅延と、ウェブサイトの操作を高速化するために入力遅延を最小限に抑える方法について説明します。
入力遅延とは何ですか?
入力遅延とは、ユーザーがページを最初に操作したとき(画面のタップ、マウスのクリック、キーの押下など)から、その操作のイベント コールバックが実行を開始するまでの時間です。すべてのインタラクションの開始時には、一定の入力遅延が発生します。

入力遅延の一部は避けられません。オペレーティング システムが入力イベントを認識してブラウザに渡すには、常に一定の時間がかかります。ただし、この部分の入力遅延はほとんど気付かれません。また、ページ自体で発生する他の事象によって、入力遅延が長くなり、問題が発生することもあります。
入力遅延について考える
一般的に、ユーザーのデバイスに関係なく、ウェブサイトがInteraction to Next Paint(INP)指標の「良好」な基準を満たせるように、インタラクションのすべての部分をできるだけ短くする必要があります。入力遅延を抑制することは、このしきい値を満たすための手段の一つにすぎません。
したがって、INP の「良好」な基準を満たすために、入力遅延をできるだけ短くする必要があります。ただし、入力遅延を完全に解消することはできません。ユーザーがページを操作しようとしているときに、メインスレッドの過剰な処理を回避している限り、入力遅延は問題を回避できる程度に低くする必要があります。
入力遅延を最小限に抑える方法
前述のように、入力遅延の一部は避けられませんが、一方で、入力遅延の一部は回避できます。入力の遅延が長い場合は、次の点を考慮してください。
過剰なメインスレッド処理を開始する繰り返しタイマーを回避する
JavaScript には、入力遅延に影響する可能性がある、よく使用される 2 つのタイマー関数(setTimeout
と setInterval
)があります。2 つの違いは、setTimeout
は指定した時間後に実行されるようにコールバックをスケジュールする点です。一方、setInterval
は、n ミリ秒ごとに、または clearInterval
でタイマーが停止するまで、コールバックを実行するようにスケジュールします。
setTimeout
自体に問題はありません。実際、長いタスクを回避するために役立つ場合があります。ただし、タイムアウトが発生するタイミングと、タイムアウト コールバックの実行時にユーザーがページの操作を試みるかどうかによって異なります。
また、setTimeout
はループまたは再帰で実行できます。この場合、setInterval
に似た動作をしますが、前の反復処理が完了するまで次の反復処理をスケジュールしないことをおすすめします。これにより、setTimeout
が呼び出されるたびにループがメインスレッドに降伏しますが、コールバックで過剰な処理が行われないように注意する必要があります。
setInterval
は一定の間隔でコールバックを実行するため、インタラクションの妨げになる可能性がはるかに高くなります。これは、setTimeout
呼び出しの単一インスタンス(ユーザー操作の妨げになる可能性がある 1 回限りのコールバック)とは異なり、setInterval
は繰り返し実行されるため、ユーザー操作の妨げになる可能性が高いため、操作の入力遅延が増加するからです。

setInterval
呼び出しによって登録されたタイマー。入力遅延が追加されると、インタラクションのイベント コールバックが通常よりも遅れて実行されます。タイマーがファーストパーティ コードで発生している場合は、タイマーを制御できます。必要かどうかを評価するか、作業をできるだけ減らすようにします。ただし、サードパーティ スクリプトのタイマーは別の話です。サードパーティ スクリプトの動作を制御できないことが多く、サードパーティ コードのパフォーマンスの問題を解決するには、関係者と連携して特定のサードパーティ スクリプトが必要なかどうかを判断し、必要な場合はサードパーティ スクリプト ベンダーに連絡して、ウェブサイトで発生する可能性のあるパフォーマンスの問題を解決するために何ができるかを判断する必要があります。
長時間のタスクを避ける
長い入力遅延を軽減する方法の一つは、長いタスクを避けることです。操作中にメインスレッドをブロックするメインスレッドの作業が多すぎると、長いタスクが完了する前に入力の遅延が増加します。

タスク内で行う処理の量を最小限に抑える(メインスレッドでできるだけ少ない処理を行うように常に努める必要があります)だけでなく、長いタスクを分割することで、ユーザー入力に対する応答性を改善できます。
インタラクションの重複に注意する
INP の最適化で特に難しいのは、重複するインタラクションがある場合です。インタラクションの重複とは、1 つの要素を操作した後、最初のインタラクションによる次のフレームのレンダリングが完了する前に、ページに対して別のインタラクションを行うことを意味します。

インタラクションの重複の原因は、ユーザーが短時間に多くのインタラクションを行うという単純なものである可能性があります。これは、ユーザーがフォーム フィールドに入力する際に発生することがあります。この場合、非常に短い時間に多くのキーボード操作が行われる可能性があります。キーイベントの処理が特に負荷が高い場合(バックエンドにネットワーク リクエストを送信する自動入力フィールドの一般的なケースなど)は、次の 2 つの方法があります。
- 入力をデバウンスして、特定の期間にイベント コールバックが実行される回数を制限することを検討してください。
AbortController
を使用して送信fetch
リクエストをキャンセルし、fetch
コールバックの処理でメインスレッドが輻輳しないようにします。注:AbortController
インスタンスのsignal
プロパティを使用してイベントを中止することもできます。
インタラクションの重複による入力遅延の原因として、負荷の高いアニメーションも考えられます。特に、JavaScript のアニメーションでは多くの requestAnimationFrame
呼び出しが発生し、ユーザー操作の妨げになる可能性があります。この問題を回避するには、可能な限り CSS アニメーションを使用して、費用のかかるアニメーション フレームのキューイングを回避します。ただし、この方法を使用する場合は、合成されていないアニメーションを避け、アニメーションがメインスレッドではなく、主に GPU とコンポーザ スレッドで実行されるようにしてください。
まとめ
入力遅延はインタラクションの実行にかかる時間の大部分を占めるわけではありませんが、インタラクションのどの部分でも時間を短縮できることを理解することが重要です。入力遅延が長い場合は、遅延を短縮する方法があります。タイマーのコールバックを繰り返さないこと、長いタスクを分割すること、インタラクションの重複に注意することは、入力遅延を減らし、ウェブサイトのユーザーがより速くインタラクションできるようにするのに役立ちます。
Unsplash のヒーロー画像(Erik Mclean 撮影)。