入力遅延の概要と、入力遅延を短縮してインタラクティビティを高速化する方法をご紹介します。
ウェブでのやり取りは複雑なものであり、ブラウザ内でさまざまな行動が引き起こされます。ただし、これらに共通するのは、イベント コールバックの実行が開始されるまでに入力遅延が生じることです。このガイドでは、入力遅延の概要と、入力遅延を最小限に抑えることで、ウェブサイトのインタラクションを高速化する方法について説明します。
入力遅延とは
入力遅延とは、ユーザーが最初にページ操作(画面のタップ、マウスのクリック、キーの押下など)を行ってから、操作のイベント コールバックの実行が開始されるまでの時間です。すべてのインタラクションは、ある程度の入力遅延から始まります。
<ph type="x-smartling-placeholder">入力遅延の一部は避けられません。オペレーティング システムが入力イベントを認識してブラウザに渡すまでには常にある程度の時間がかかります。ただし、多くの場合、入力遅延のその部分はそれほど顕著ではありません。また、ページ自体で発生する他の要因によって、入力遅延が長くなり、問題が発生することもあります。
入力遅延の考え方
一般的には、ウェブサイトでインタラクションのあらゆる部分を可能な限り短くして、Interaction to Next Paint(INP)指標の「良好」] を満たす可能性が高くなります。しきい値は、ユーザーのデバイスに関係ありません入力遅延の抑制は、このしきい値を満たすためのほんの一部にすぎません。
そのため、INP の「良好」を満たすために、入力遅延を可能な限り短くすることを目指します。あります。ただし、入力の遅延を完全に排除することはできません。ユーザーがページを操作するときにメインスレッドによる過剰な処理を避けている限り、入力遅延は問題を回避できる程度に短くする必要があります。
入力遅延を最小限に抑える方法
前述のように、ある程度の入力遅延はは避けられませんが、その一方で、ある程度の入力遅延は回避できます。長い入力遅延に苦労している場合は、次の点を考慮してください。
メインスレッドの過度な処理を発生させる繰り返しのタイマーを避ける
JavaScript でよく使用されるタイマー関数として、入力遅延の一因となる setTimeout
と setInterval
の 2 つがあります。両者の違いは、setTimeout
は指定された時間の後にコールバックが実行されるようにスケジュールする点です。一方、setInterval
は、n ミリ秒ごとに永続的に、または clearInterval
でタイマーが停止するまでコールバックを実行するようにスケジュールします。
setTimeout
自体は問題ではありません。実際、時間のかかるタスクを避けるのに役立ちます。ただし、タイムアウトが発生するタイミングと、タイムアウト コールバックの実行時にユーザーがページを操作しようとしたかどうかによっても異なります。
また、setTimeout
はループで実行することも、再帰的に実行することもできます。その場合、setInterval
のように動作しますが、前のイテレーションが完了するまで次のイテレーションをスケジュールしないことをおすすめします。つまり、setTimeout
が呼び出されるたびにループがメインスレッドに移りますが、そのコールバックが最終的に過剰な処理を行わないように注意する必要があります。
setInterval
は一定間隔でコールバックを実行するため、操作の妨げになる可能性が高くなります。これは、setTimeout
呼び出しの単一インスタンス(ユーザー インタラクションの妨げになる可能性がある 1 回限りのコールバック)とは異なり、setInterval
は繰り返し発生する性質のため、インタラクションの妨げになる可能性が非常に高いため、インタラクションの入力遅延が増加するためです。
タイマーがファーストパーティ コードで発生する場合は、そのタイマーを制御できます。その作業が必要かどうかを評価します。また、作業量をできるだけ減らすように最善を尽くします。ただし、サードパーティ スクリプトのタイマーについては別の話です。多くの場合、サードパーティ スクリプトの機能を制御することはできません。サードパーティのコードのパフォーマンスの問題を解決するには、多くの場合、関係者と協力して特定のサードパーティ スクリプトが必要かどうかを判断する必要があります。必要な場合は、サードパーティのスクリプト ベンダーに連絡して、ウェブサイトで発生する可能性のあるパフォーマンスの問題を解決するために何ができるかを判断します。
長いタスクを避ける
長い入力遅延を軽減する方法の一つは、長いタスクを避けることです。インタラクション中にメインスレッドをブロックするような過剰なメインスレッドの処理があると、長いタスクが完了する前にメインスレッドの入力遅延が増加します。
<ph type="x-smartling-placeholder">常にメインスレッドで行う作業量を最小限に抑えるだけでなく、長いタスクを分割してユーザー入力に対する応答性を高めることもできます。
インタラクションの重複に注意する
複数のインタラクションが重複している場合は INP の最適化が特に難しくなります。インタラクションの重複とは、ある要素を操作した後、最初のインタラクションが次のフレームを表示する前に、ページで別のインタラクションを行うことを意味します。
<ph type="x-smartling-placeholder">インタラクションの重複の原因としては、ユーザーが短期間に多くのインタラクションを行うような単純なケースもあります。これは、ユーザーがフォームのフィールドに入力している場合に発生することがあります。これは、非常に短い期間で、多くのキーボード操作が行われる場合です。キーイベントの作業に特にコストがかかる場合(ネットワーク リクエストがバックエンドに対して行われる予測入力フィールドの一般的なケースなど)は、次の 2 つのオプションがあります。
- 入力のバウンス解除によって、一定期間内にイベント コールバックが実行される回数を制限することを検討してください。
AbortController
を使用して送信fetch
リクエストをキャンセルし、メインスレッドがfetch
コールバックの処理で輻輳しないようにします。注:AbortController
インスタンスのsignal
プロパティを使用して、イベントの中止を行うこともできます。
インタラクションの重複により入力遅延が増加するもう 1 つの原因は、コストの高いアニメーションです。特に、JavaScript のアニメーションでは多数の requestAnimationFrame
呼び出しが発生し、ユーザーの操作の妨げとなる可能性があります。この問題を回避するには、可能な限り CSS アニメーションを使用し、コストがかかる可能性のあるアニメーション フレームがキューに追加されないようにします。ただし、その場合、アニメーションがメインスレッドではなく GPU スレッドとコンポジタ スレッドで主に実行されるように、非合成アニメーションを避けるようにします。
まとめ
入力の遅延は、インタラクションの実行にかかる時間の大部分を占めているわけではありませんが、インタラクションのあらゆる部分に時間がかかることを理解しておくことが重要です。入力遅延が長い場合は、遅延を短縮できます。タイマー コールバックの繰り返しを回避したり、長いタスクを分割したり、インタラクションの重複に注意したりすることは、入力遅延の短縮につながり、ウェブサイトのユーザーのインタラクティビティを高速化することができます。
Unsplash のヒーロー画像(Erik Mclean)