モバイルCLS 0.41の原因を特定し、本文画像の寸法補完を実装した

  • #Core Web Vitals
  • #CLS
  • #画像
  • #自動化

今回やったこと

モバイルのCumulative Layout Shift(CLS)が0.41まで悪化した問題を、本文画像にwidthheightが無いことから切り分けた。目視で「表示が遅い」と判断するのではなく、画像が読み込まれる前にブラウザが確保できる寸法があるかを調べ、投稿経路と既存記事の両方を直す構成にした。

実測の対象はモバイル幅375px、画面高812px。1記事では本文画像3枚の読み込み時に合計632pxのレイアウト移動が発生した。内訳は158px、237px、237pxである。さらに直近100本では65本が寸法なし画像を持ち、208個のimgタグのうち184個に寸法が無かった。Search Consoleで確認したモバイルCLSは0.41、不良しきい値は0.25、対象URLは339件だった。

なぜ寸法だけでレイアウトが動くのか

画像に寸法が無いと、ブラウザは画像データを読み込むまで表示領域の高さを確定できない。先に描画された本文の下へ画像が挿入されるため、読み込み完了時に後続の本文が押し下げられる。HTMLへ寸法属性を加えると、読み込み前から縦横比に基づく予約領域を置ける。

この処理はCSSの見た目を変えるためのものではない。既存のmax-width:100%などの指定はそのままにし、予約寸法だけを与える。画面幅375px(左右余白16pxを除いたコンテンツ幅343px)で640×295の画像を表示する場合、高さは343 * 295 / 640の丸めで158pxになる。1510×1042の画像も同じ計算で237pxになるため、実測の移動量と一致した。

<img src="https://example.invalid/image.webp" width="1510" height="1042" loading="lazy">

1つではなく3つの書き込み経路を塞ぐ

新しい投稿だけを直しても、別の経路から寸法なしタグが流入する。そこで画像寸法を補完する共通処理を作成し、まとめ投稿の合流点、HTML下書き投稿、既存記事への挿絵追加という3経路へ組み込んだ。画像パイプラインは、投稿直後に手元へある画像を読めるため、ローカルの寸法取得処理を使う。

経路役割寸法の扱い
まとめ投稿複数の作成・編集経路の合流点共通関数で補う
HTML下書き投稿特集記事やデータ集など共通処理で補う
画像パイプライン既存記事へ挿絵を追加ローカル画像から補う

処理は、両方の属性が既にあるタグを上書きしない。片方だけある場合は、その値を残し、元画像から取得した縦横比をもとに不足側を計算する。data:画像、SVG、相対パスは対象外とし、寸法を取得できない画像はタグを変更せず通過させる。取得失敗で公開全体を止めると、CLSも直らず記事も出ないためだ。

既存記事はバックフィルで扱う

投稿側を直しても、既に公開された記事は自動では変わらない。バックフィル処理はWordPressの編集用raw本文を読み、寸法を加えたcontentだけを書き戻す。rendered本文を書き戻すとショートコードが展開済みの文字列で固定されるため、rawを対象にする。差分が無い記事は更新せず、取得できない画像もそのままにする。

検証スクリプトでは、3経路の呼び出し、寸法付与、既存属性の非破壊、片側属性の補完、対象外形式の通過、取得失敗時のfail open、自己終了タグの保持を確認する。さらに寸法なし画像を公開前検査がWARNとして検出し、寸法あり画像では鳴らないことも確認する。実装の有無だけでなく、全経路へ接続され、失敗時の挙動まで決まっていることが重要になる。

実装ステータスと更新履歴

実装済み・稼働中。この記事の数値は、検証環境における実測記録に基づく。

  • 更新履歴: 2026-09-11 初稿。
  • 訂正履歴: なし。