2024年3月12日、Googleは新しいCore Web Vital指標である Interaction to Next Paint (INP) を開始することを発表しました。INPは、FID(First Input Delay)に代わるもので、Googleによるサイトのパフォーマンス評価の方法を変え、最終的に検索エンジンの検索結果に影響を与えます。
TL;DR:3月12日以降にあなたのサイトが悪影響を受けないよう、今日からINPに最適化する必要があります。
INPへ変更した経緯
FID(First Input Delay)は、Webページがユーザーの最初のアクションに対してどれだけ速く反応するかを測定するために設計されました。一般的に良いとされるFIDスコアは、100ms以下とされています。
しかしChromeの使用データによると「ユーザーのページ滞在時間の90%は読み込み後に費やされる」ため、FIDではユーザー体験のすべてを把握することはできません。
そこで INPは、最初のインタラクションだけでなくページ上のユーザージャーニー全体にわたってクリック、タップ、キーの押下を観察するように設計することで、ページの全体的な知覚応答性を測定することが可能になっています。
最終的なINPの値は、ユーザーがアクションを実行してから視覚的なフィードバックを受け取るまでに観測された最長時間として計算されます。
ユーザーインタラクションの例としては、製品をカートに追加するボタンのクリック、展開可能なアコーディオンのクリック、折りたたまれたナビゲーションメニューのタップ、入力フィールドへの入力などがあります。
INPは、特定のアクションが実行された後、視覚的フィードバックが表示されるまでの時間(つまり、次のペイント-ここでペイントとは、ブラウザがスクリーンにピクセルを追加するプロセスのことです)に焦点を当て、インタラクションの最終的な効果(ネットワークリクエストやUIの更新など)は除外します。
開発ツールにおけるINPの調査
Chrome、Brave、Edge、ArcなどのChromiumベースのブラウザを使用して、INP測定値に寄与するアクションとイベントを調査する方法を見てみましょう。
INPが計測する以下のユーザーインタラクションのいずれかを受け付けるウェブページを選択します(スクロールやポインタの移動などは計測されない)
- マウスでのクリック
- タッチスクリーンを使ってデバイスをタップする
- 物理キーボードまたはオンスクリーンキーボードのキーを押す
今回は、Sentry Docsのホームページで “web vitals “を検索したときに何が起こるかを調査することにしました。
開発ツールパネルを開き、「パフォーマンス」タブをクリックします。
Webサイトのターゲット層にもよりますが、古いマシンや低速のインターネット上でのユーザー体験を分析するために、CPUやネットワーク速度を調整することはしばしば有用です。
より遅いCPUやネットワークをシミュレートしたい場合は、それに応じてオプションを設定してください。
記録ボタンをクリックし、ページ上でいくつかのインタラクションを実行します。
録画を停止し、プロファイルがロードされるのを待ちます。
すると、色分けされたブロックとラベルの付いたレーンの形で、多くのデータが表示されます。
INPの要因を分析する際に最も重要なレーンは、”Interactions”(ページ上で実行されたユーザーインタラクション)と “Main”(ブラウザのメインスレッド)です。
文脈上、メインスレッドは “ブラウザがユーザーイベントとペイントを処理する場所 “です。デフォルトでは、ブラウザはメインスレッドを使用して、ページ上のすべてのJavaScriptの実行、ページのレイアウト、あらゆる変更の再計算、メモリの確保と解放(ガベージコレクション)を行います。
つまり、長時間実行されるJavaScript関数がメインスレッドをブロックする可能性があり、レスポンスの悪いページや悪いユーザーエクスペリエンスにつながります。GoogleはINPメトリックを導入することで、開発者にこれを解決するよう促しています。
記録されたパフォーマンスプロファイルを見ると、メインスレッドのブロックが赤くハイライトされていることがあります。タスクにカーソルを合わせると、実行にかかった時間が表示され、そのタスクブロックの下には、そのタスクを構成する個別のイベントや関数呼び出しがすべて表示されます。
マウスやトラックパッドでズームイン/ズームアウトしたり、ウィンドウの右側にあるスクロールバーを使ってスタックを上下にスクロールすることができます。
レーンの下にあるサマリー・タブは、各タスクでどれだけの時間が異なるプロセスに割り当てられたかを示しています。
これはタスクによって異なりますが、通常は「スクリプティング」(つまりJavaScriptの処理)と「ローディング」に最も長い時間がかかっていることが明確になります。
では、メインスレッドのアクティビティと、インタラクションレーンを確認してみましょう。
この例では、Sentry Docsホームページの検索入力に “web vitals “と入力した状態です。
メインスレッドのタスクブロックの下に、それぞれの文字を入力したときにキャプチャされた “Event: keypress “ブロックがいくつもあるのがお分かりでしょうか。
インタラクションレーンには、”Keyboard “と書かれたブロックがありますが、これは私がいつタイプしたかを示している。これらのブロックにカーソルを合わせると、”Long interaction is causing poor performance “と表示されます。
ブロックの両側にも注目してください。これはメインスレッドのアクティビティによってインタラクションがブロックされていることを示しています。
私がタイピングしているとき(CPUスロットリングを使用しているとき)、この無反応は明らかでした。キーボード・インタラクションのブロックをクリックすると、このインタラクションをさらに調べることが可能です。
要約を見ると、このインタラクションの入力遅延は45ms、処理時間は83.1ms、表示遅延は84.638msだということが分かりました。インタラクションの総時間は212.74msかかっています。
Googleは、良いINPスコアを200ms以下、悪いINPスコアを500ms以上、改善が必要とされるスコアは200〜500msの間であると定義しています。
これらのベンチマークに基づいて、Webページの改善が必要になります。
各タスクの中でどのプロセスに最も時間がかかっているかを理解するには、タスクブロックを選択し、下の「Bottom-Up」タブをクリックします。
これは、どのアクティビティが直接、合計で最も時間を要したかを示しています。「Total Time」列のヘッダーをクリックすると、時間の昇順または降順でソートできます。
各イベントを展開すると、後続イベントの全リストとそれぞれの実行時間が表示されます。この詳細なリストと、あなたが想定しているイベントを比較することで、異常を特定することができます。
ウェブサイトやアプリのINPを改善する
開発におけるメインスレッドアクティビティとの相互参照によってブロッキングプロセスを調査する方法についてはご理解いただけたでしょうか。
それでは次に、INPのスコアが悪くなる問題をどのように修正すればよいのかが課題です。
INPスコアに影響を与える可能性のある予期しない長時間実行タスクをWebページで発見した場合に、問うべき質問をいくつか紹介します。
- タイムリーな視覚的フィードバックを提供しているか?次のペイントは200ms以内に行われるか?
- 予期しないときに何かが実行されていないか?そのプロセスを削除できるか?
- 各ユーザーのインタラクションを個別に処理する必要が本当にあるのか?デバウンスによって関数呼び出しを制限することができるか?
- メインスレッドから関数呼び出しを抽出してウェブワーカーに移すことはできるか?
ページの応答性を向上させる実験的な方法もありますが、すべてのブラウザでサポートされているわけではないのでご注意ください。
navigator.scheduling.isInputPending()
Chromiumブラウザのみのサポートですが、isInputPending()を使用すると、イベントキューに保留中の入力イベントがあるかどうかをチェックすることができます。
これは、実行すべきタスクのキュー(キー押下ごとの API 呼び出しなど)がある場合に便利で、定期的にメインスレッドに制御を戻してページがユーザとの対話に応答できるようにします。本稿執筆時点では、このAPIを他のブラウザ・エンジンで利用可能にする計画は公表されていません。
scheduler.yield
scheduler.yieldは、scheduler APIを拡張して、setTimeout()を使って手動でコードの実行を延期するようになっています。
これまで使われていた方法よりも「簡単で優れた」メインスレッドへの制御の引き渡し方法です。
どちらの新しいAPIも、ブラウザのJavaScriptが実際にどのように動作するのかを理解するための良い機会を提供してくれますが、結局のところ、すべてのブラウザに対応していないため、ベストプラクティスとは呼べません。
クロスブラウザJavaScriptタスクスケジューラ
この投稿のための調査中に見つけた、Antonio Stoilkov氏によって開発されたJavaScriptタスクスケジューラである「main-thread-scheduling」をご紹介します。
使用可能な場合はisInputPending()を使用しますが、すべてのブラウザにスケジューリング機能を提供します。個人的には、これをテストするユースケースはまだありませんが、一見したところ、現在メンテナンスされており、試してみる価値はありそうです。
結論
FIDに代わる新しいINP Core Web Vitalを導入することで、開発者はユーザージャーニー全体にわたって視覚的フィードバックの遅延を最小限に抑えることを優先することが推奨されます。
これにより、Webページがユーザーのアクションに反応していることをユーザーに安心させることができ、理論的には、摩擦や直帰率を減らし、全体的なWeb体験を向上させることができます。
たとえ、フロントエンドでデータを取得したりAPIサービスを呼び出したりするのにかかる時間を、常に完全にコントロールできるわけではないとしても、INPスコアを上げるためには、常にページが速く感じられるようにする必要があります。
Sentryはまた、3月12日からGoogleの新しいCore Web Vital、INPのサポートを追加します。
Sentryで貧弱なINPにどのように対処できるようになるのか、またSentryのWeb Vitalで何ができるのかについては、こちらをご覧ください。
不明点があれば、いつでもGitHubやDiscordでご連絡ください。