上級者向け

第3回: 「重い」を許さない。Core Web VitalsとINPの外科手術

第3回「重い」を許さない。Core Web VitalsとINPの外科手術
WEB先案内

2024年以降、GoogleのUX評価はCore Web Vitals(コアウェブバイタル)という
LCP / CLS / INP の3指標を中心に設計されています。

PageSpeed Insights のスコアは悪くない。
それでも、

  • クリックすると一瞬止まる
  • 入力やスクロールに引っかかりを感じる

この違和感を放置しているサイトは、2024年以降、確実に評価を落とします。

その正体が INP(Interaction to Next Paint) です。

本記事では、

  • なぜ「表示は速いのに重く感じる」のか
  • 何がINPを悪化させているのか
  • どこを見て、どこを切ればよいのか

を、現場で使えるレベルまで分解します。

INPとは何か。何を測り、何を測らないのか

INP(Interaction to Next Paint)の定義

重要なのは、INPは次のものを直接は測っていないという点です。

  • 通信速度
  • 初回表示速度
  • サーバーレスポンス単体

つまり、

  • 読み込み速度は良い
  • ページはすぐ表示される

それでも、

  • ボタンを押すと一瞬止まる
  • 入力時に引っかかる

この「操作中の詰まり」を数値化するのが INP です。

INPの評価基準(目安)

なぜ PageSpeed Insights だけでは足りないのか

PageSpeed Insights(PSI)は有用なツールです。しかし INP改善の主戦場ではありません

理由は以下です。

  • PageSpeed Insightsはスコア(合否)を知るには適しているが、『どの操作が遅いのか』という原因特定には向いていない
  • 静的な読み込みシナリオが主体
  • ユーザー操作中の詰まりを再現しにくい

INPはユーザーが操作した「その瞬間」に何が起きているかを問題にします。

そのため、使うべきツールは Chrome DevTools です。

Chrome DevTools:INP改善で見るべきポイント

Performance タブをクリックすると LCP・CLS・INPを確認できます。

Performanceタブとは何か

INP改善では、特に以下を見ます。

  • Experience
  • Main Thread
  • Long Tasks
Main Threadとは何か

ここが占有されると、

  • 入力を受け付けない
  • 描画が遅れる

結果として INPが悪化 します。

Long Taskとは何か

この50msという閾値は、人間が「引っかかり」を感じ始める境界として定義されています。

INPが悪いサイトには、必ずこの Long Task が存在します。

JavaScript実行遅延と「犯人プラグイン」の特定

なぜJavaScriptがINPを悪化させるのか?

ユーザー操作は、次の流れで処理されます。

  1. 入力イベント発生
  2. JavaScriptイベントハンドラ実行
  3. DOM更新
  4. 描画

という流れで処理されます。

この途中で、

  • 重いJavaScript
  • 同期処理
  • 不要な初期化

が挟まると、描画が遅れ、INPが悪化します。

特定手順

  1. Chrome DevTools → Performanceタブ
  2. 実際に「重い操作」を行う
  3. 記録を停止する
  4. Main Thread を確認
  5. 50ms超の Long Task を探す
  6. Call Tree / Bottom-Up を確認

用語補足

  • Call Tree:処理の呼び出し関係
  • Bottom-Up:処理時間の消費順

重要なのは「どこから始まったか」ではなく、
何が時間を消費しているか」です。

なぜテーマよりプラグインが原因になりやすいのか

  • テーマJS:ページ単位で制御されやすい
  • プラグインJS:全ページ常駐しやすい

特に以下は要注意です。

  • DOMContentLoaded 後に重い初期化を行うJS
  • ユーザー操作をフックして同期処理を行うJS
  • 管理画面とフロントで共用されているJS

これらはInteraction直後に実行され、INPを直撃します。

画像最適化の最終解とlazy-loadの落とし穴

AVIF / WebP の実務的な使い分け

現時点での現実解は以下です。

  • AVIF:対応ブラウザ向け
  • WebP:フォールバック
  • JPEG:最終保険

picture 要素での出し分けが基本です。

lazy-load が INP を悪化させる理由

loading="lazy" は万能ではありません。

lazy-load は
表示を遅らせる技術であって、速くする技術ではありません。

問題が起きやすいケース

  • ファーストビュー内の画像
  • LCP候補画像
  • ヒーロー画像

これらを lazy にすると、

  1. 初回描画では画像なし
  2. ユーザー操作発生
  3. 画像取得+描画が発生
  4. Main Threadが占有

結果、操作と描画が競合し INP が悪化します。

原則:LCPには「優先タグ」を、それ以外には「遅延」を

  • ファーストビュー(LCP画像)
    loading="lazy" は使用しない。さらに、モダンブラウザ向けに fetchpriority="high" 属性を付与することを推奨します。これにより、ブラウザに対して「これは最優先で取得すべきリソースだ」と明示でき、描画開始を早めることができます。
  • 下層画像(ファーストビュー外)
    loading="lazy" を使用して、初期ロードの阻害を防ぎます。

Object Cache(Redis / Memcached)が「毒」になる瞬間

Object Cache は強力ですが、条件次第では逆に遅延要因になります。

なぜキャッシュなのに遅くなるのか

Object Cacheは、

  • PHP → Redis → PHP

という往復処理を増やします。

Object Cache は魔法ではありません。導入することで以下のコストが新たに発生します。

  1. ネットワークレイテンシ:
    WebサーバーからRedisサーバーへの通信時間
  2. シリアライズ/デシリアライズ:
    データを保存・復元するための変換処理コスト

キャッシュヒット率が低い場合、またはキャッシュするデータ自体が巨大な場合、単純にPHPで再計算する時間」よりも「Redisからデータを取ってくる時間」の方が長くなるという逆転現象(オーバーヘッド)が発生します。 これが、キャッシュを入れているのにサイトが重い、INPが悪化するという現象の正体です。

INPへの影響

  • 操作イベント中にキャッシュ確認
  • Redis応答待ち
  • JavaScript処理と競合

これにより、操作後の描画が遅れます

対策の考え方

  • すべてキャッシュしない
  • 動的ブロックは対象外
  • Query Monitorでヒット状況を確認

Query Monitor再考:見るべきはHTTP待機時間

Query Monitor=スロークエリ
という理解は不十分です。

現代のWordPressは、

  • REST API
  • 外部API
  • JavaScriptフェッチ

に強く依存しているためHTTP APIに注目する必要があります。

なぜHTTP API Callsを見るべきか

Query Monitor の HTTP API Calls では、

  • 外部リクエストの待機時間
  • ブロッキングの有無

を確認できます。これらが JavaScript 実行中に重なると、INPに直結します。

上級者Q&A

Q1. CDNキャッシュが効かない「動的ブロック」とは何ですか?

表示時に毎回サーバー側の処理が走り、内容が固定されないブロックのことです。

具体的には、

  • ユーザーごとに内容が変わる
  • 時間・状態・権限によって表示が変わる
  • PHP / REST API / 外部API を毎回呼び出す

といった特性を持つブロックを指します。

Q2. なぜ動的ブロックは CDN キャッシュが効かないのですか?

HTMLをキャッシュすると、本来変わるべき内容まで固定されてしまうからです。

動的ブロックをHTMLキャッシュすると、以下の事故が起きます。

  • 他人の情報が表示される
  • ログイン状態が混線する
  • 管理者向け情報が一般ユーザーに見える
  • 表示条件が壊れる

つまり、
速度と引き換えに安全性を失う状態になります。

そのため、動的ブロックはCDNキャッシュの対象にしてはいけません

Q3. では、動的ブロックは一切キャッシュできないのですか?

いいえ。ブロック全体」をキャッシュしないだけです。

ポイントは、
静的部分と動的部分を分離することです。

Q4. 「切り離す」とは、具体的にどういう意味ですか?

役割ごとに処理を分ける、という意味です。

部分処理方法
ページ全体のHTMLCDN / ページキャッシュ
固定文言・レイアウト静的HTMLとして配信
ユーザー依存・状態依存Ajax / REST API で後読み

これにより、

  • ページは高速に表示される
  • 動的情報は必要な分だけ取得される
  • CDNキャッシュと衝突しない

という状態を作れます。

Q5. なぜ Ajax / REST API に分けると安全なのですか?

HTMLキャッシュと責務が分離されるからです。

Ajax / REST API は、

  • キャッシュしない
  • ユーザー単位で処理できる
  • 権限チェックを個別に行える

という特性があります。

つまり、

  • 表示速度は CDN に任せる
  • 個別処理は API に任せる

という安全な分業構造が作れます。

Q6. Edge Cache や ESI(Edge Side Includes)で解決できませんか?

ケースによりますが、過信は危険です。

理由は、

  • ESI対応CDNは限られる
  • 実装が複雑になりやすい
  • WordPress側の責務が不透明になる

ためです。

実務では、

「まずは静と動を分ける」
それ以上の最適化は必要になってから

が安全な判断です。

Q7. INP(体感速度)との関係は?

動的ブロックを切り離すと、INPが安定します

理由は、

  • ページ描画時に余計な処理が走らない
  • Main Thread をブロックしない
  • ユーザー操作と描画が競合しにくい

からです。

INPが悪いサイトでは、
操作直後に動的処理が走っている ケースが非常に多く見られます。

Q8. 結局、どう判断すればいいですか?

次の質問に「YES」が多いブロックは、動的として切り離すべきです。

  • ユーザーごとに内容が変わるか
  • 毎回PHP処理やAPI通信が走るか
  • キャッシュすると事故が起きそうか
  • 操作直後に処理が走っていないか

1つでも怪しければ、
HTMLキャッシュ対象にしない判断が正解です。

今すぐできる INP改善チェックリスト

最後に、本記事の内容を自サイトに適用するためのチェックリストをまとめました。まずはこれらを潰すだけで、改善の糸口が見えるはずです。

  • LCP画像の確認:
    ファーストビュー画像の loading="lazy" を削除し、fetchpriority="high" を記述したか?
  • Long Taskの特定:
    Chrome DevToolsで操作中に「50ms以上」の赤いバーが出ているか確認したか?
  • プラグインの選別:
    全ページで読み込まれている不要なプラグインJavaScriptを停止したか?
  • 動的ブロックの隔離:
    ログイン状態やユーザー情報を含むブロックを、HTMLキャッシュから除外(またはJS化)したか?

まとめ

第1回では「何が起きているか」をログから特定しました。
第2回では「構造としてどこに無理があるか」を設計視点で整理しました。

そして第3回では、
ユーザー操作で何が詰まっているのかをINPを軸に可視化してきました。

ここで見えてきたのは、
パフォーマンス問題の多くがJavaScriptとレンダリングの境界で起きているという事実です。

以下に、本記事の要点を箇条書きでまとめおきます。

  • INPは「操作中の詰まり」を暴く指標
  • 点数より DevTools
  • JS Long Task が最大の敵
  • キャッシュも使い方次第で毒
  • 計測 → 切除 → 再計測
次回、第4回では

「動かない」の深層。React / Headless / JSエラーの外科解剖
に進みます。

PHPだけでは解決できない世界に、さらに踏み込みましょう。

ココナラよりも安い!

ウェブナラはじめました!

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

ABOUT ME
WEBさん
WEBさん
WordPressの不具合をなおす人
あなたのお仕事をする時間を使ってITに関することを調べたり、トライしてみたりして、それでもうまくいかない。そんなことはありませんか? WEB先案内をご利用いただくと、困ったときにITの顧問としてあなたのITに関するお悩みにお答えし、サポートを行うことができます。
記事URLをコピーしました