この記事で扱うこと
ランディングページの性能を改善しながら学んだ三つを整理する。特定の製品・数値は外し、どこでも通じる一般概念だけを扱う。最大の学びは 遅い LCP の本当の原因を診断で確定すること だった — 直感(「画像を減らそう」)が間違っていた。
今日扱ったこと
| 作業 | 何をしたかったか | やったこと | 結果 |
|---|---|---|---|
| LCP 診断・改善 | 遅い LCP を直したかった | breakdown で render delay を確認 → サーフェスをサーバー化 | 画像ではなく hydration がボトルネック |
| スクロールモーション | ランディングモーションを印象的にしたかった | 派手なスクロール従属演出 → 進入スタッガーリビールに確定 | アクセシビリティ・離脱リスク減少 |
| FAQ 構造化 | FAQ を検索リッチ結果にも露出 | FAQ アコーディオン + 構造化データを画面と 1:1 に | ポリシー準拠、リッチ結果候補 |
1. LCP が遅いのに画像が小さければ hydration を疑え
どんな状況だったか。 ランディングの LCP(最大コンテンツが描かれる時刻)が遅かった。直感的に「ヒーロー画像を減らそう」が浮かんだが、画像はすでに小さかった。本当の原因を診断で確認する必要があった。
核心概念。 LCP は四つの区間(TTFB / load delay / load time / render delay)に分けられる。画像が小さくサーバー応答も正常なのに render delay が大きければ、犯人はダウンロードではなく LCP 要素がクライアントコンポーネント境界の中にあり、hydration が終わって初めて描かれること だ。hydration はサーバーが作った静的 HTML に後から JavaScript でイベントを付けて動くようにする過程で、LCP 要素がその中に閉じ込められるとペイントが JavaScript の実行に人質に取られる。メインスレッドが空いている(TBT≈0)のに LCP だけ遅いなら、この場合の可能性が高い。
やったこと。 breakdown で render delay がボトルネックだと確定し、攻略対象を画像ではなく ランディングのクライアント JS 除去 に定めた。ヒーロー・上部ストーリーセクションをサーバーコンポーネント + CSS アニメーションに変え、重いコンテキストプロバイダ(認証/クエリ/モーション/サービスワーカー)をアプリサーフェス専用レイアウトに下ろし、静的ランディングチャンクから完全に外した。副産物として、フレームワークが初期 HTML の <img> を自動 preload することも分かり、大きな元画像を小さく表示していたブランドマークを専用の小型アセットに分離した。
教訓。 LCP が遅いのに TBT が 0 で画像が小さければ element render delay を見よ — クライアント境界内の LCP 要素は hydration がペイントを押しのける。処方はアセットではなくそのサーフェスのクライアント JS 除去だ。スコアの停滞が測定シミュの下限のためなら、止めるのが正しい(過投資防止)。
→ LCP element render delay — hydration がペイントを押しのける
2. 派手なスクロールモーションより節度ある進入スタッガー
どんな状況だったか。 ランディングセクションのモーションを印象的にしようとスクロールに従属した派手な演出(スクロールを掴んで段階的に進める)を押し進めたが、フィードバックは繰り返し「重い」だった。
核心概念。 スクロールジャッキング(scroll-jacking)はユーザーのスクロールを横取りして画面を勝手に掴む技法で、乗り物酔い・離脱を誘発しアクセシビリティガイド(Motion Sensitivity)で違反とみなされる。代替はスタッガーリビール — 要素をビューポートに入るとき少しずつ時間差で現しつつ、スクロールは掴まない節度ある演出だ。
やったこと。 スクローラー自体を除去し、ビューポート進入スタッガーリビールに確定した。reduced-motion ユーザーにはすぐ最終状態でレンダーするようゲートを置いた。
教訓。 派手なスクロール従属モーションより短い進入スタッガーリビールが汎用的な正解であることが多い。
3. 構造化データは画面と 1:1
どんな状況だったか。 FAQ を入れながら検索リッチ結果(FAQ スニペット)まで狙った。ただし画面のアコーディオンと検索エンジンに入れる構造化データが食い違うとポリシー違反になる。
核心概念。 構造化データ(JSON-LD)は検索エンジンに「これは FAQ だ」を伝える機械向けの情報だ。FAQPage タイプは 画面に実際に見える Q&A と 1:1 でなければならない(可視コンテンツ一致)。こっそり別のものを入れるとペナルティだ。
やったこと。 FAQ をネイティブ <details> アコーディオンで入れ、構造化データを画面と同じ items 配列でビルドした(pure builder + 項目がなければ script を省略するパターン)。
教訓。 FAQ 構造化データは画面に見える Q&A と 1:1 でなければならない。