読み込み中に「ガクッ」と動くストレス#
Webページを見ているとき、あと少しで読み込み終わる...というタイミングで、突然画像が表示されて文章の位置がズレたり、タップしようとしたボタンが動いて広告を誤クリックしてしまったりした経験はありませんか?
この現象を CLS (Cumulative Layout Shift: 累積レイアウトシフト) と呼びます。 Googleの Core Web Vitals の指標の一つであり、**「視覚的な安定性」**を測るものです。CLSスコアが悪い(0.1以上)と、SEO順位に悪影響を及ぼすだけでなく、ユーザーに強烈なストレスを与えます。
この問題の最大の原因は、**「画像(やiframe)のサイズが指定されていないこと」**にあります。
1. なぜサイズ指定が必要なのか?#
ブラウザがHTMLを読み込んで描画(レンダリング)する際、画像のデータ(jpg/png)がダウンロードされるまで、その画像の「大きさ」は分かりません。 そのため、最初は高さ0pxで描画し、画像データが届いた瞬間に「あ、これは高さ300pxだ」と判断して、後続のコンテンツをガガッと下に押し下げます。これがレイアウトシフトの正体です。
これを防ぐには、**「ここは後で300pxの画像が入るから、あらかじめ場所を空けておいてね」**とブラウザに伝える必要があります。それが width と height 属性です。
<!-- Bad: 画像が読み込まれるまで高さ不明 -->
<img src="photo.jpg" alt="Photo">
<!-- Good: アスペクト比が計算され、読み込み前からスペースが確保される -->
<img src="photo.jpg" alt="Photo" width="800" height="600">
現代のブラウザは、HTMLの width と height 属性から自動的にアスペクト比(縦横比)を計算し、CSSが読み込まれる前でもスペースを確保してくれます。
2. CSS aspect-ratio プロパティ#
レスポンシブデザインで、横幅を%指定(可変)にする場合でも、CSSの aspect-ratio プロパティを使えば高さを自動計算してスペースを確保できます。
.card-image {
width: 100%;
height: auto;
aspect-ratio: 16 / 9; /* 横幅に応じて、16:9の比率で高さを確保 */
object-fit: cover;
}
3. Webフォントによるズレ (FOUT / FOIT)#
画像だけでなく、Webフォント(Google Fontsなど)の読み込みもレイアウトシフトの原因になります。 デフォルトフォント(MS ゴシックなど)が表示された後、Webフォントに切り替わる瞬間に文字の幅や高さが変わるためです。
対策:size-adjust の活用
CSSの size-adjust プロパティを使うと、代替フォントの大きさをWebフォントに合わせて調整し、切り替わりのズレを最小限に抑えることができます。
また、Next.js の next/font を使えば、この調整を自動で行ってくれます。
4. 動的コンテンツの落とし穴#
広告バナーや、非同期で読み込まれるウィジェット(Twitterの埋め込みなど)もCLSの常習犯です。 これらを配置する場合は、あらかじめ min-height (最小の高さ) をCSSで指定し、コンテンツが入るための「枠」を確保しておきましょう。
.ad-slot {
min-height: 250px; /* 広告が入るエリアを先に確保しておく */
background: #f0f0f0; /* スケルトンスクリーン風の背景色 */
}
「プレースホルダー(場所取り)」を制する者が、CLSを制します。ユーザーに快適な読書体験を提供するために、ピクセル単位の「おもてなし」を心がけましょう。

VIIO 編集部
VIIOのパフォーマンス改善チーム。Webパフォーマンスとアクセシビリティの向上に情熱を注いでいます。複雑な技術をわかりやすく伝えることをモットーに記事を執筆中。