INPの入力遅延(Input Delay):原因、診断、および修正方法

入力遅延によって引き起こされるINPの問題を見つけて改善する方法を学ぶ

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-04

入力遅延によるInteraction to Next Paint (INP) の問題

このページは、私たちのInteraction to Next Paint (INP)シリーズの一部です。INPは、ユーザーのインタラクションから次の視覚的な更新までの合計時間を測定します。入力遅延は、INPを構成する3つのフェーズのうちの最初のものであり、それに処理時間(processing time)表示遅延(presentation delay)が続きます。INPを初めて扱う場合は、まずINPの問題を特定して修正する方法のガイドをお読みください。

INP TIP: ほとんどの場合、入力遅延はWebページの初期読み込み段階で発生します。これは、ブラウザがスクリプトの解析と実行で最も忙しいときです。

入力遅延とは何ですか?

入力遅延とは、ユーザーがWebページを操作(ボタンのクリックやキーの押下など)した後、ブラウザがイベントコールバックの処理を開始するまでにかかる時間を指します。常にある程度の入力遅延は存在しますが(ブラウザでさえコールバックをスケジュールするための時間を必要とします)、ブラウザが他のスケジュールされたタスクの実行で忙しく、インタラクションによって要求されたコールバックをすぐにスケジュールできない場合、過度な入力遅延が発生します。

入力遅延の間、ユーザーはすでにアクション(クリック、タップ、またはキー押下)を実行していますが、ブラウザは関連するイベントハンドラーの実行をまだ開始していません。ユーザーには何の応答も見えません。これは、イベントハンドラーがアクティブに実行されている処理時間や、ブラウザが視覚的な更新をレンダリングしている表示遅延とは異なります。入力遅延は、メインスレッドの輻輳によって引き起こされる純粋な待機時間です。

入力遅延とINP

Interaction to Next Paint (INP) は、「入力遅延(Input Delay)」、「処理時間(Processing Time)」、および「表示遅延(Presentation Delay)」の3つのサブパートに分類できます。

入力遅延と、古いCore Web Vitalsである「First Input Delay(FID)」の間に名称の類似性があることに気づくかもしれません。Interaction to Next Paintは、2024年3月にCore Web VitalsとしてFIDに代わるものとなりました。First Input Delayは、最初のインタラクションとイベントコールバックの間の時間のみを測定していました。FIDは廃止されましたが、入力遅延は依然として重要です。なぜなら、それがすべてのInteraction to Next Paint測定の基盤にあるからです。

入力遅延の重要性

多くの開発者はコールバック関数を最適化する(処理時間を最適化する)という観点からINPの改善を考えるため、入力遅延は見過ごされがちです。確かに、入力遅延は通常、INPの最大の部分ではありませんが、入力遅延を最適化すれば、多くの場合、すべてのINPのインタラクションを一度に最適化することになります。入力遅延を減らすことで、最悪のものだけでなく、ページ上のすべてのインタラクションが向上します。

CoreDashでは、毎時間数百万のCore Web Vitalsデータポイントを収集しています。そのデータに基づくと、入力遅延はInteraction to Next Paintの約18%を占めています。これは処理時間や表示遅延よりも少ないですが、入力遅延は多くの場合、最も簡単に削減できるフェーズです。なぜなら、その根本的な原因はほぼ常に「タイミング悪く実行されるJavaScriptが多すぎる」ことだからです。

入力遅延の原因

入力遅延は、メインスレッドが他のタスクの実行で忙しい場合に発生します。これらのタスクの原因には以下のものがあります:

  1. 初期のタスク(Early tasks)。早い段階でキューに入れられた通常のスクリプト、deferスクリプト、およびasyncスクリプトは、初期のタスクを作成します。これらは、ユーザーがページを操作する可能性が最も高い重要な起動ウィンドウ中に実行されるため、入力遅延の最も一般的な原因となります。
  2. スケジュールされたタスク(Scheduled tasks)。一部のタスクはページ読み込みの開始時には実行されませんが、ページが読み込まれた後にスケジュールされる場合があります。これらのタスクもINPに干渉し、入力遅延を引き起こす可能性があります。たとえば、window.onloadイベントの後に実行されるスクリプトや、いわゆる最適化プラグインによって遅延されるスクリプトなどです。JavaScriptのasyncとdeferの使い分けについて詳しく学んでください。
  3. 繰り返しタスク(Repeat tasks)setInterval()を介した繰り返しのタスクで、実行に比較的長い時間がかかり、INPと同時に発生するもの。
  4. 重複するコールバック(Overlapping callbacks)。重複するコールバックは、入力遅延の一般的な原因です。複数のコールバックが互いに近いタイミングでスケジュールされるとキューが作成され、次のインタラクションの処理が遅れる可能性があります。たとえば、clickハンドラーの直前に発生するmouseoverハンドラーは、mouseoverタスクの期間だけクリックの処理を遅らせる可能性があります。

入力遅延を最小限に抑える

入力遅延を最小限に抑えるには、ユーザーがページを操作する直前にブラウザが(長い)タスクを実行していないことを確認する必要があります。これは、タスクをより適切な時間にスケジュールしたり、タスクが長時間実行されないようにしたり、タスクの実行中にインタラクションを防いだりすることで実現できます。
  1. 長い初期タスクを複数の小さなタスクに分割する。長いタスクの間、ブラウザはユーザー入力に応答できませんが、各短いタスクの後はブラウザがユーザー入力に応答できます。scheduler.yield()を使用するか、各関数をsetTimeout(callback, 0)でtimeoutを0にしてラップすることで、長いタスクを分割します。
  2. インタラクティブな要素の管理。 インタラクティブな要素(検索バーなど)を制御するJavaScriptコードが完全に読み込まれる前に、それらを提示しないことを検討してください。これにより、クリックを受け取る準備ができていない要素への早期のクリックを防ぐことができます。このパターンのUXを最適化するには、必要なJavaScriptの読み込みを優先するか、要素が機能するようになるまで一時的に非表示または無効化することができます。
  3. アイドル時間のスクリプト実行。重要ではないスクリプトは、requestIdleCallback()を使用してブラウザのアイドル期間中に実行するようにスケジュールします。この関数はブラウザがアイドルのときに実行され、ユーザー入力を処理する必要がありません。
  4. Webワーカーを使用して、ブラウザのメインスレッド外でJavaScriptを実行する。 Webワーカーを使用すると、スクリプトをメインスレッドの外部で実行できます。これにより、メインスレッドがブロックされてINPの入力遅延の問題が発生するのを防ぐことができます。
  5. 繰り返しタスク中に保留中の入力がないか確認する。スケジュールされたタスクのセットを実行する前に、タスクを開始する前に保留中の入力がないか確認してください。保留中の入力がある場合は、まずメインスレッドにyieldします。
  6. 不要なコードを削除する。各コード行はInteraction to Next Paintに影響を与える入力遅延を引き起こす可能性があるため、定期的にスクリプトを監査し、不要なコードやスクリプト全体を削除します。実践的なテクニックについては、JavaScriptを遅延させる14の方法のガイドを参照してください。

scheduler.yield()を使用したタスクの分割

scheduler.yield() APIは、長いタスクを分割するための推奨される方法です。継続部分をタスクキューの後ろに配置するsetTimeout(callback, 0)とは異なり、scheduler.yield()はタスクの優先度を維持します。これは、保留中のユーザー入力を処理した後、ブラウザができるだけ早くコードを再開することを意味します。以下は再利用可能なヘルパー関数です:

async function yieldToMain() {
  if ('scheduler' in window && 'yield' in window.scheduler) {
    return await window.scheduler.yield();
  }
  // Fallback for browsers without scheduler.yield()
  return new Promise((resolve) => {
    setTimeout(resolve, 0);
  });
}

// Example: break up a long initialization sequence
async function initializeApp() {
  loadCriticalFeatures();
  await yieldToMain();  // Let the browser handle any pending input

  loadSecondaryFeatures();
  await yieldToMain();

  loadAnalytics();
  await yieldToMain();

  loadNonEssentialWidgets();
}

scheduler.yield()の内部での動作について詳しくは、Chrome Developers ブログをご覧ください。

scheduler.postTask()を使用したタスクの優先順位付け

scheduler.yield()がタスクを分割するのに対し、scheduler.postTask()はタスクの優先度をきめ細かく制御できるようにします。このAPIは3つの優先度レベルを受け入れます:最高の優先度を必要とする重要なタスクのための"user-blocking"、中程度の優先度のタスクのための"user-visible"、そしてアイドル時間に実行されるべき最も低い優先度のタスクのための"background"です。

postTask()を使用すると、重要ではない作業がユーザーのインタラクションをブロックしないようにすることができます。以下は、UIの更新を最高の優先度に保ちながら、分析作業をbackground優先度でスケジュールする実践的な例です:

// High priority: UI feedback runs first
scheduler.postTask(() => {
  showLoadingSpinner();
}, { priority: 'user-blocking' });

// Medium priority: fetch data
scheduler.postTask(async () => {
  const data = await fetchSearchResults(query);
  renderResults(data);
}, { priority: 'user-visible' });

// Low priority: analytics can wait
scheduler.postTask(() => {
  trackSearchEvent(query);
  sendToAnalytics('search', { query });
}, { priority: 'background' });

本番環境で使用する前に、scheduler.postTask()のブラウザサポート表を確認してください。APIをサポートしていないブラウザの場合は、バックグラウンドタスクにはrequestIdleCallback()、優先度の高いタスクにはqueueMicrotask()へのfallbackを使用します。

実践的な意味合い

これはあなたのサイトにとって何を意味するのでしょうか?以下はWordPressとReact/Next.jsの具体的な推奨事項です。

WordPress

WordPressは、そのプラグイン駆動のアーキテクチャにより、多くの場合、1つのテーマと多数のプラグインが付属しています。プラグインとテーマはどちらも、機能を実現するためにJavaScriptに依存することがよくあります。これらのプラグインやテーマはサードパーティの開発者によって維持されているため、あなたはコンテンツを制御できません。つまり、ファイルを変更して「悪いコード」を最適化することはできません。今日スクリプトがうまく動作していたとしても、次回の更新後もそうなるという保証はありません。

WordPressで入力遅延を最小限に抑え、Interaction to Next Paint (INP) を最適化するには、次の手順を実行します:

  • 可能な限りプラグインの使用を避ける。プラグインは機能を追加する簡単な方法ですが、ページにスクリプトを追加することがよくあります。これらのスクリプトはINPに影響を与える入力遅延を引き起こします。各プラグインについて自問してください:カスタムコードやサーバー側のソリューションで同じ機能を実現できるか?
  • 軽量なテーマを選択する。 多くのWordPressテーマは「すべてを提供」します。それは素晴らしいアイデアのように思えますが、使用されていないにもかかわらず貴重なCPU時間を占有する機能で満たされている可能性が高いことを意味します。
  • ページビルダーを避ける。 ElementorやWPBakeryなどのページビルダーは、レイアウトを構築するためのユーザーフレンドリーで視覚的なインターフェースを提供します。残念ながら、訪問者にそのレイアウトを提示するために重いスクリプトに依存していることがよくあります。
  • 必要な場合にのみスクリプトを読み込む。WordPressには、すべてのページにすべてのスクリプトを読み込む傾向があります。これを修正するには、子テーマを作成し、ページタイプごとに不要なスクリプトの登録を解除します:
function my_deregister_scripts() {
  if ( ! is_page( 'contact' ) ) {
    // Deregister contact form script on non-contact pages
    wp_dequeue_script( 'contact-form-script' );
  }
}
add_action( 'wp_enqueue_scripts', 'my_deregister_scripts' );
  • Tag Managerを監査する。Google Tag Managerコンテナには、時間の経過とともにタグが蓄積されることがよくあります。ページの読み込み中に発火する各タグは、メインスレッドにタスクを追加します。未使用のタグを削除し、適切なトリガーを設定し(たとえば、コンバージョンページでのみマーケティングタグを発火させる)、Tag Managerに組み込まれているタイミングレポートを使用して遅いタグを特定します。
  • 重要ではないサードパーティのスクリプトを遅延させる。チャットウィジェット、フィードバックツール、およびソーシャルメディアの埋め込みは、すぐに読み込む必要はありません。requestIdleCallback()やスクロールベースのトリガーを使用して、ユーザーがそれらを必要とする可能性が高いときにのみ読み込むようにします。詳細な戦略については、JavaScriptを遅延させる14の方法のガイドをお読みください。

React / Next.js

ReactおよびNext.jsサイトは主にJavaScriptで動いています。スタートアップスクリプトの実行、コンポーネントのハイドレーション、仮想DOMの処理にはすべて時間がかかり、Interaction to Next Paint (INP) の入力遅延を引き起こす可能性があります。良いニュースとして、ReactとNext.jsはどちらもこれを効果的に管理するためのツールを提供しています。

  • サーバーコンポーネント(Next.js App RouterのReact Server Components)を使用する。サーバーコンポーネントはサーバー上でレンダリングされ、クライアントにJavaScriptを送信しません。これにより、メインスレッドの時間を競合するコードの量が直接減少します。
  • 正しい戦略でサードパーティのスクリプトを読み込む。 Next.jsでは、ハイドレーション後に必要なスクリプトにはstrategy="afterInteractive"を使用し、ブラウザのアイドル時間に読み込めるスクリプトにはstrategy="lazyOnload"を指定したnext/scriptコンポーネントを使用します。基本的な原則については、JavaScriptのasyncとdeferの使い分けのガイドを参照してください。
  • idle-until-urgentパターンを実装する。このパターンは、重要でない初期化にrequestIdleCallback()を使用しつつ、コンポーネントが実際に必要になったときにアクティブになる同期的なfallbackを維持することで、バックグラウンドタスクよりもユーザーインタラクションを優先します。
  • コンポーネントを遅延読み込み(Lazy load)する。 React.lazy()や、クライアント専用コンポーネント向けの{ ssr: false }を指定したNext.jsのdynamic()を使用して、すぐには必要ないコンポーネントを遅延読み込みします。
  • インタラクティブなコンポーネントにSuspenseを使用する。インタラクティブなコンポーネントを<Suspense>バウンダリでラップして、重いコンポーネントがバックグラウンドで読み込まれている間に、ページの残りの部分がレンダリングされインタラクティブになるようにします。これにより、単一の遅いコンポーネントがページ全体の入力処理をブロックするのを防ぎます。
  • 緊急性のない更新にReact transitionsを使用する。重要でない状態の更新をstartTransition()でラップし、ユーザーが新しいインタラクションを実行したときにReactがそれらを中断できるようにします。これにより、大規模な再レンダリングが進行中の場合でも、UIの応答性が維持されます。

他のINPフェーズについて調べる

INPを制御下に置くには、他の2つのフェーズにも対処してください:

  • 処理時間(Processing Time):インタラクション中に実行されるイベントハンドラーコードを最適化します。ほとんどのページで、ここで最適化の努力の大部分が報われます。
  • 表示遅延(Presentation Delay):イベント処理に続くレンダリングとペイントの作業を減らします。大きなDOMを持つ複雑なページでは、これが最大のフェーズになることがよくあります。

完全な診断ワークフローについては、INPの問題を見つけて修正する方法のガイドを参照し、完全な概要についてはINPハブページに戻ってください。

何が本当に遅いのか、見つけ出します。

フィールドデータでCritical Rendering Pathをマッピング。Lighthouseレポートではなく、優先順位付きの修正リストをお渡しします。

監査を依頼する
INPの入力遅延(Input Delay):原因、診断、および修正方法Core Web Vitals INPの入力遅延(Input Delay):原因、診断、および修正方法