【実務・中級編】 Interaction to Next Paint (INP) の計測 – Webブラウザの仕組み実践ガイド

INP(Interaction to Next Paint)を制する者は、UXの泥沼から脱出できる

やあ。今日はフロントエンド開発の「ラスボス」とも言える、Interaction to Next Paint (INP) について語ろうと思う。

Core Web Vitalsの指標として定着して久しいが、正直に言おう。INPを「ただのスコア」だと思っているなら、君のサイトはまだユーザーのイライラを解消できていない可能性が高い。

INPは、単なる通信速度の話じゃない。「ブラウザのメインスレッドという限られたリソースを、君がどう使いこなしているか」という、エンジニアの腕がそのまま反映される極めてシビアな指標なんだ。

—

ブラウザの裏側で何が起きているのか?

まず、INPが計測するのは「ユーザーの操作から、次のフレームが描画されるまでの時間」だ。これを分解すると、ブラウザが内部でやっていることは以下の3段階に集約される。

1. 入力遅延 (Input Delay): ユーザーがクリックした瞬間、メインスレッドが他のタスク(重いJSの実行など)で埋まっていて、イベントリスナーが起動できない時間。
2. 処理時間 (Processing Time): イベントハンドラが実行され、DOMの変更やロジックの計算が行われる時間。
3. 表示遅延 (Presentation Delay): 変更されたDOMを計算(Recalculate Style / Layout)し、画面に描画(Paint / Compositing)するまでの時間。

現場で一番多い落とし穴は、「2」を高速化しようとして、結果的に「1」を悪化させるパターンだ。例えば、Reactの`useMemo`や`useCallback`を多用しすぎて、JSの評価コストが爆上がりしているケースがその典型だな。

—

実務で使える!INP計測の決定版コード

まずは、自分のサイトで何が起きているのかを可視化しなければ始まらない。`web-vitals`ライブラリを使うのが最も確実だが、まずは「何が起きているか」を把握するための計測スクリプトを共有する。

これをエントリポイント(`index.js`など)に貼って、コンソールを眺めてみてくれ。

import { onINP } from ‘web-vitals’;

/

  • INPの各フェーズを詳細に分析するためのラッパー
  • ユーザーが「遅い!」と感じるボトルネックを特定します

/
function logINPDetails(metric) {
// ユーザーの操作から描画までの全工程
const value = metric.value;

// 100ms以内なら理想的、200msを超えるとユーザーは「カクつき」を感じる
const rating = value <= 200 ? 'GOOD' : value <= 500 ? 'NEEDS IMPROVEMENT' : 'POOR'; console.group(`[INP Analysis] - ${rating}`); console.log(`合計遅延時間: ${value}ms`); // 実際の実務では、PerformanceObserverを使って // 「Input Delay」と「Processing Time」のどちらが支配的かを見るのがコツ // これが長いなら、Long Taskがメインスレッドを占有している証拠 console.log('ヒント: 合計値の大部分がInput Delayなら、メインスレッドの開放を優先してください。'); console.groupEnd(); } // 計測を開始 onINP(logINPDetails); ---

泥臭い現場の最適化テクニック

コードを計測して「ああ、やっぱり遅いな」と気づいた後、君たちが取るべきアクションは3つしかない。

1. メインスレッドを「明け渡す」 (Yielding)

重い処理を1つの塊で実行してはいけない。`setTimeout`でタスクを分割するのも手だが、最新のブラウザなら `scheduler.yield()` が使える。これを使って、ブラウザに「今なら描画していいよ」と隙間を作ってやるんだ。

async function heavyTask() {
const data = await fetchData(); // 重いデータ処理

// ブラウザのレンダリングに割り込むチャンスを作る
if (‘scheduler’ in window && scheduler.yield) {
await scheduler.yield();
}

// 残りの処理を実行
updateDOM(data);
}

2. 不要な「リフロー」を誘発しない

CSSの変更は、ブラウザにとって最もコストのかかる仕事の一つだ。JSでDOMを何度も書き換えるのではなく、一度の変更に集約する。`requestAnimationFrame` を使って、描画のタイミングをブラウザのレンダリングサイクルに同期させるのがプロの作法だ。

3. イベントリスナーを賢く絞る

「全部のクリックに反応する」なんて設計は論外だ。イベント委譲(Event Delegation)を使い、DOMツリーの深い階層でリスナーを増やさないこと。メモリリークの温床になるし、何よりメインスレッドの負荷が上がる。

—

最後に:エンジニアとしての心構え

INPを最適化するということは、ユーザーの「心地よさ」という目に見えない価値を追求することだ。

計測値が良くなっても、それはあくまで数字に過ぎない。君が書いたコードが、低スペックなスマホを使っているユーザーにどう届いているか。その想像力を働かせることが、ただのコーダーと、真のフロントエンド・アーキテクトを分かつ境界線だ。

まずは今日、自分のサイトを触って、どこで「引っかかり」を感じるか、自分の感覚とスコアを照らし合わせてみてほしい。そこからが、本当の戦いの始まりだよ。健闘を祈る。

コメント

タイトルとURLをコピーしました