Googleが試験導入したパフォーマンス指標のINPについて
2022年5月くらいからGoogleがINPという指標を試験導入していたらしいです(知らんかった…)。
多分今頃感すごいですが、今回はweb.devのブログ内容をもとにINPについてと、INPの計測や、モダンフレームワークの差などを話していこうと思います。
参考文献
ほぼ以下の参考文献をもとにしているので、下を読んだ方がより正しい情報を得られます。
Interaction to Next Paint (INP)
How do modern frameworks perform on the new INP metric
INPとは何か
まず、INPとは何かについてですがINPはInteraction to Next Paintの略です。
web.devのブログの説明によるとユーザがなんらかのアクションをしてから、ページが応答する速度のことらしいです。
(web.devのブログから引用)
つまり、上記のようにボタンなどのインタラクションを操作してからローディング画面になって、データが表示されるまでの速度みたいな感じですね。
レイテンシの評価
INPの計測で、対象のインタラクションは以下の三つです。
- マウスのクリック
- タッチスクリーンでのタップ
- 物理キーボードまたはオンスクリーンキーボードにおけるキー入力
INPでは、上記のインタラクションに関して以下の三つの速さを計算していきます。
- 入力遅延(input delay)
ユーザーがページを操作してからイベントハンドラーが実行されるまでの時間 - 処理時間(processing time)
関連するイベントハンドラーでコードを実行するのにかかる合計時間 - 表示遅延(presentation delay)
イベントハンドラーの実行が終了してからブラウザーが次のフレームを表示するまでの時間
処理時間は、三つのインタラクションのなかで最も遅い操作とするらしいです。
そして、上記のレイテンシを、ページ内のインタラクション数を指標として、選択することで、以下の表のようにINPの値が決まります
ページ内のインタラクションの数 | INPとして採用されるインタラクション要素 |
---|---|
1-49 | 最大のレイテンシ |
50-99 | 2番目に大きいのレイテンシ |
100-149 | 3番目に大きいのレイテンシ |
150-199 | 4番目に大きいのレイテンシ |
200-249 | 5番目に大きいのレイテンシ |
250-299 | 6番目に大きいのレイテンシ |
300-349 | 7番目に大きいのレイテンシ |
350-399 | 8番目に大きいのレイテンシ |
400-449 | 9番目に大きいのレイテンシ |
450以上 | 10番目に大きいのレイテンシ |
常に最悪のレイテンシを使用しないのは、インタラクションの数が増えるほど、最悪のレイテンシが平均のレイテンシとの差が開いてしまうためらしいです。
INPの良さについて
INPの評価は以下の3段階で行われます。
- 200ミリ秒: ページの応答性が良好である
- 200ミリ秒より上で、500ミリ秒以下: ページの応答性を改善する必要がある
- 500ミリ秒より上: ページの応答性が低い
200ミリ秒以下を目指せよな!ってことですね。
INPの計測ツール
上記までがINPの説明です。
Google様はINPの計測ツールも作ってくれています。
web.devのブログのサイトではいくつか紹介されています。
-
PageSpeed Insights.
urlを入力すると以下のように出力されます。ただ、十分なユーザデータが必要です
ちなみに以下は某ショッピングサイトの結果ですが、まあ、満たしてるだろうなぁと思って計測したら、満たしておらず驚きました。最近発表されたものであるので、今後は対応していくのかなと思います。
-
Chrome User Experience Report (CrUX).
確かにINPの項目があります -
web-vitals JavaScript library.
onINP()で測れるっぽいです - Lighthouse npm module.
- Lighthouse User Flows.
-
Web Vitals extension for Chrome.
ページ内で何度かインタラクションを行うと以下のように結果が表示されます(以下は私のブログ(Next.js)の結果です。ダメダメでした)
INPの改善
改善方法もweb.devのブログで紹介されていました。
ページ起動時
- 未使用のコードを削除
- JavaScriptの遅延読み込みをする
- 低速のサードパーティJavaScriptの特定
- 最適化できるタスクを最適化する
- JavaScriptを実行した後、必要でない処理を削除する(コンポーネントの再レンダリングなど)
ページ起動後
- タスクの適切な優勢順位づけ
- ブラウザがアイドル状態の時に必須ではない作業をスケジュールする
- タスクの最適化
- サードパーティのJavaScriptの監査
モダンフレームワークとINP
モダンフレームワークとINP達成率
モダンフレームワークでは、INPへの対応がまだ十分ではなく、個別の対応が必要なようです。
CWVテクノロジーレポートのデータではINPの合格%は以下のようになっているらしいです(テーブルの結合ができませんでした)
Technology | % Passing | |
---|---|---|
% Mobile | Desktop | |
Angular (v2.0.0+) | 19.0 | 65.5 |
Next.js | 20.2 | 73.4 |
Nuxt.js | 25.4 | 84.5 |
Preact | 36.6 | 90.6 |
Vue (v2.0.0+) | 41.7 | 90.0 |
Lit | 36.4 | 75.7 |
結構Vueが高いですね。なぜなのかは分かりませんが。
JavaScriptのどのような部分がINPに関わっているか
モダンフレームワークのJavaScriptのどこの部分がINPに関わっているかというと以下の部分らしいです。
- 最適化しされていないJavaScript: いらないコードなどを消したり、コードを分割することで応答時間の改善につなげられる
- サードパーティのコード: インタラクションの処理には必要のないサードパーティのコードが影響することがあります
- 複数のイベントハンドラー: 複数のイベントハンドラーは相互に干渉して合計して長い遅延が発生する可能性がある。Webワーカーなどでアイドル状態の時にスケジュールするなどを考えられる
- イベント処理のフレームワークオーバーヘッド: Vueのv-onなどのフレームワーク独自のイベント処理のオーバーヘッドが関係する可能性がある
- ハイドレーション: JavaScriptからHTML生成をする際の時間が遅延に関係する可能性
- プリフェッチ: 今後必要になるリソースを積極的にプリフェッチしておくことが遅延に関係する
フレームワークのINP改善
ReactとNext.js
startTransitionとSuspeneseを使用することで選択的にコンポーネントのレンダリング処理の実装ができ流ので、これによってINPが改善できるらしいです。
また、Next.jsはstartTransitionを使用する新しいルーティングフレームワークを作っており、これを使用して応答性の向上ができるとのことです
Angular
現状実現していないが、いくつかアイデアがある
- ゾーンレス: バンドルサイズの削減
- ハイドレーション: インタラクションのためにアプリを起動する必要がある量を制限するアイランドスタイルのハイドレーション(筆者<何を言っているのかいまいちわからない)
- CDのオーバーヘッドを削減する: 変更検出のコストを削減する。
- よりきめ細かいコード分割: バンドルを小さくする
- 読み込みインジケーターのサポート向上
- プロファイリングツール: インタラクションのコストを理解することができる開発ツールの作成
まとめ
INPはまだ実験的ですが、今後採用された場合はコンポーネントの部分的なレンダリングやプリフェッチをますます重視しないといけなくなる気がしました。
Discussion