- HTMLが早く出るほどレイアウトは揺れやすくなる
- CLSとは何を測っているのか
- SSRでなぜ発生しやすいのか
- フォントロードが最大の原因になる
- 画像も同じ問題を起こす
- なぜLCPとトレードオフになるのか
- 対策:フォント表示戦略
- 対策:画像のサイズ指定
- もう一つの原因:非同期CSS
- 結局なぜ起きるのか
HTMLが早く出るほどレイアウトは揺れやすくなる
SSR(Server Side Rendering)は初期表示が速く、LCP改善に効果があると説明されることが多いです。
しかし運用を始めると、別の指標が悪化するケースがあります。CLS(Cumulative Layout Shift)です。
「表示は速くなったのにスコアが下がった」
この現象は珍しくありません。原因はレンダリングの失敗ではなく、表示が早すぎることにあります。
SSRはHTMLを即表示できるため、ブラウザが「未確定のレイアウト」を先に描画します。その後、リソースが揃った瞬間に再配置が発生し、レイアウトシフトが記録されます。
CLSとは何を測っているのか
CLSは単なる再描画回数ではありません。
「ユーザーが見ている間に要素の位置がどれだけ動いたか」を測定します。
例:
- ボタンが下にズレる
- 見出しが押し出される
- 画像の高さが変わる
重要なのは「視覚的な移動」です。
表示が速くても、配置が変わるとCLSは悪化します。
SSRでなぜ発生しやすいのか
SSRでは、HTML到着直後にブラウザはレイアウトを計算します。
しかしこの時点では次の情報が不足しています。
- Webフォントの幅
- 画像サイズ
- 非同期CSS
つまりブラウザは「仮のサイズ」で描画します。
後からリソースが到着すると、実際のサイズに合わせて再計算が行われます。
これがレイアウトシフトです。
SPAではJS実行後にまとめて描画されるため、初回配置が確定しやすく、逆にCLSが出にくい場合があります。
フォントロードが最大の原因になる
特に影響が大きいのがWebフォントです。
フォントが到着するまで、ブラウザは代替フォントを使用します。
流れ:
1. SSR HTML描画(代替フォント)
2. Webフォント取得
3. フォント置換
4. 文字幅が変化
5. 行折返し変更
6. レイアウト移動
これをFOUT(Flash of Unstyled Text)と呼びます。
文字の幅が変わるため、段落全体が上下に動き、CLSが計測されます。
画像も同じ問題を起こす
画像も同様です。
HTMLにサイズ指定がない場合、ブラウザは高さを0として扱います。
<img src="/hero.jpg">
画像読み込み後:
- 高さが確定
- 下のコンテンツが押し下げられる
これもCLSになります。
なぜLCPとトレードオフになるのか
LCPを改善するには「早く表示」する必要があります。
しかし早く表示すると、リソース未確定状態で描画が始まります。
結果:
- LCP改善
- CLS悪化
つまり同時最適化が難しい指標です。
対策:フォント表示戦略
有効なのはフォント表示方法の制御です。
@font-face { font-family: "MyFont"; src: url("/font.woff2") format("woff2"); font-display: swap; }
font-displayの意味:
| 値 | 挙動 |
| swap | 代替フォント→置換 |
| block | 表示待機 |
| optional | 取得失敗時は置換しない |
CLSを抑えるには、フォントサイズ差の少ない代替フォントを選ぶことも重要です。
対策:画像のサイズ指定
画像は必ずサイズを指定します。
<img src="/hero.jpg" width="1200" height="630">
これによりブラウザはレイアウトを確定できます。
読み込み後も位置は変わりません。
もう一つの原因:非同期CSS
遅延ロードされたCSSもレイアウトシフトを引き起こします。
特にファーストビューのスタイルを後から適用すると、大きく揺れます。
critical CSSをインライン化すると改善します。
結局なぜ起きるのか
SSR
「未完成でも表示する」
SPA
「完成してから表示する」
この差がCLSの差です。
SSRはユーザーに早く見せる代わりに、レイアウト確定前の画面を見せてしまいます。
CLS対策は難しい最適化ではありません。
ブラウザが最初に計算したレイアウトを変えないことです。
- フォント幅を揃える
- 画像サイズを指定する
- 重要CSSを先に出す
SSRは表示を早める技術ですが、完成度の低い画面を出しやすい技術でもあります。
表示速度の最適化は「速さ」だけでは完結しません。
「最初の1回のレイアウトをどれだけ安定させるか」が、最終的なユーザー体験を決めます。