無限スクロールは、実装するだけならそれほど難しくありません。
IntersectionObserver でローダーを監視し、下部に近づいたら次の投稿を追加すれば基本形は完成します。
しかし、本番サイトで使う場合は、それだけでは不十分です。
長くスクロールしたときに重くならないか、戻るボタンで位置が復元されるか、検索エンジンが内容を認識できるか、キーボード操作でも使えるか。
こうした点を考えないまま導入すると、見た目は便利でも使いにくい画面になってしまいます。
この記事では、無限スクロールを実運用する前に確認したいUX、アクセシビリティ、SEO、パフォーマンスの重要ポイントを解説します。
読み込み状態を明確に表示する
無限スクロールでは、ユーザーが明示的に「次へ」ボタンを押すわけではありません。
そのため、システムが今何をしているのかが見えにくくなります。
最低限、読み込み中であることを表示しましょう。
<div id="loader" class="loader">
<div class="spinner"></div>
<span>読み込み中...</span>
</div>
ただし、本番では「読み込み中」だけでは不十分です。
状態に応じて表示を変えることが大切です。
- 読み込み中:読み込み中です
- エラー時:読み込めませんでした。再試行してください
- 終端:すべて読み込みました
- 空の場合:表示できるコンテンツがありません
ユーザーが迷いやすいのは、失敗したときと終わったときです。
この2つをはっきり表示するだけで、無限スクロールの体験はかなり改善します。
エラー時に再試行できるようにする
API通信では、ネットワークエラーや一時的なサーバーエラーが起こることがあります。
エラー時に何も表示しないと、ユーザーは読み込み中なのか、止まっているのか判断できません。
再試行ボタンを表示して、ユーザーが自分で復帰できるようにしましょう。
catch (error) {
loader.innerHTML = `
<p>読み込めませんでした。</p>
<button type="button" id="retry">再試行</button>
`;
document.querySelector("#retry").addEventListener("click", loadMore);
}
無限スクロールは自動処理ですが、失敗時には手動操作を用意しておくことが重要です。
追加された内容を支援技術に伝える
スクリーンリーダーを使っているユーザーには、新しいコンテンツが追加されたことが伝わらない場合があります。
その場合は、aria-live を使って状態を通知します。
<div id="feed-status" class="sr-only" aria-live="polite"></div>
const status = document.querySelector("#feed-status");
status.textContent = "10件の投稿を追加しました";
aria-live="polite" は、現在の読み上げを邪魔しにくい形で更新内容を伝える指定です。
投稿本文をすべて読み上げさせる必要はありません。
「何件追加されたか」を伝えるだけでも、画面の変化を理解しやすくなります。
キーボード操作に対応する
無限スクロールは、マウスやタッチ操作では自然に使えます。
しかし、キーボードで操作する場合は注意が必要です。
投稿が増えるほど、フォーカスできるボタンやリンクも増えていきます。
そのため、Tabキーで移動しているユーザーが現在位置を見失うことがあります。
確認すべきポイントは次の通りです。
- クリックできる要素を
buttonやaで作っているか - フォーカスリングが見えるか
- 読み込み後にフォーカスが勝手に移動しないか
- 先頭へ戻るリンクがあるか
- 主要な操作をキーボードだけで使えるか
見た目だけでなく、操作できるかどうかまで確認しましょう。
戻るボタンでスクロール位置を復元する
無限スクロールでよくある不満が、詳細ページから戻ったときに一覧の最初へ戻ってしまうことです。
長くスクロールしたあとに位置が失われると、ユーザーは大きなストレスを感じます。
本番では、次の情報を保存しておくと復元しやすくなります。
- 現在のスクロール位置
- 読み込んだページ数
- 次に取得するcursor
- 表示済みの投稿ID
- 検索条件や並び替え条件
保存先としては、history.state や sessionStorage が使えます。
ユーザーが詳細ページから戻ったときに、同じ位置へ復元できるように設計しましょう。
DOMが増え続ける問題に注意する
無限スクロールでは、閲覧を続けるほどDOM要素が増えます。
投稿が数百件、数千件と増えると、スクロールや描画が重くなる可能性があります。
対策として、次の点を検討します。
- 1回に追加する件数を増やしすぎない
- 画像を遅延読み込みする
- 不要なイベントリスナーを増やしすぎない
- カードの高さを安定させる
- 大量データでは仮想スクロールを検討する
仮想スクロールとは、画面に見えている範囲の要素だけをDOMに残す方法です。
大量のログ一覧や管理画面では効果的です。
ただし、検索エンジンやブラウザ内検索との相性には注意が必要です。
画像は遅延読み込みする
画像付きのフィードでは、画像の読み込みが体感速度に大きく影響します。
画像が多い場合は、loading="lazy" を使って遅延読み込みを設定しましょう。
<img
src="sample.jpg"
alt="投稿画像の説明"
width="800"
height="500"
loading="lazy"
>
width と height を指定しておくと、画像が読み込まれる前に表示領域を確保できます。
これにより、読み込み後に画面がガタつくレイアウトシフトを防ぎやすくなります。
CSSでは、aspect-ratio を使う方法も有効です。
.post-image {
aspect-ratio: 16 / 10;
overflow: hidden;
}
無限スクロールでは、スクロール位置のズレが体験を悪くするため、画像領域の高さを先に確保することが大切です。
SEO用にページネーションURLを用意する
無限スクロールは、検索エンジンとの相性に注意が必要です。
JavaScriptで後から追加されるコンテンツが、すべて正しく認識されるとは限りません。
検索流入を重視する記事一覧や商品一覧では、無限スクロールだけに依存しないほうが安全です。
たとえば、次のようなページネーションURLを用意します。
/articles/page/1/
/articles/page/2/
/articles/page/3/
ユーザーには無限スクロールで見せつつ、検索エンジンや共有用にはページ単位のURLを持たせる設計です。
これにより、クロール、共有、再訪、アクセス解析がしやすくなります。
フッターに到達できる設計にする
無限スクロールでは、下へ進むたびに新しいコンテンツが追加されます。
そのため、フッターに到達しにくくなることがあります。
フッターに重要なリンクを置いている場合は、次のような対策を検討しましょう。
- 一定回数読み込んだら自動読み込みを止める
- 途中から「さらに読み込む」ボタンに切り替える
- 固定ナビゲーションに重要リンクを置く
- フッターとは別に問い合わせリンクを用意する
特に、会社情報、問い合わせ、利用規約、プライバシーポリシーなどは、ユーザーが確実にアクセスできる場所に置くべきです。
「さらに読み込む」ボタンとの併用も考える
完全自動の無限スクロールが常に最適とは限りません。
サイトによっては、「さらに読み込む」ボタンを併用したほうが使いやすい場合があります。
たとえば、次のような使い方です。
- 最初の数回だけ自動読み込みにする
- 一定件数以降はボタン式にする
- 最初からボタンで明示的に読み込ませる
ニュースサイト、コーポレートサイト、検索結果一覧では、完全自動よりもボタン式のほうが親切なことがあります。
ユーザーに読み込みタイミングを委ねることで、フッターにも到達しやすくなります。
実装前チェックリスト
無限スクロールを本番サイトに入れる前に、次の項目を確認しましょう。
- 読み込み中の表示がある
- エラー時に再試行できる
- 最後まで読み込んだことがわかる
- 二重読み込みを防いでいる
- 戻るボタンで位置が復元される
- キーボードだけで操作できる
- 追加された内容を必要に応じて通知している
- 画像の遅延読み込みをしている
- 画像サイズを指定している
- SEO用のページネーションURLがある
- フッターや重要リンクへ到達できる
- 長時間閲覧しても重くなりすぎない
このチェックを通すことで、単に動くだけではなく、実際にユーザーが使いやすい無限スクロールに近づきます。
まとめ
無限スクロールは、ユーザーを自然に次のコンテンツへ誘導できる便利なUIです。
しかし、本番サイトで使う場合は、読み込み処理だけでなく、UX、アクセシビリティ、SEO、パフォーマンスまで考える必要があります。
- 読み込み状態を表示する
- エラー時に再試行できるようにする
- 戻るボタンで位置を復元する
- DOMが増え続けないようにする
- 画像の読み込みを最適化する
- 検索エンジン用のページURLを用意する
これらを整えることで、見た目だけではなく、実用性の高い無限スクロールになります。
無限スクロールは、SNS風フィード、記事一覧、画像ギャラリー、レコメンド一覧などに応用できます。
導入するときは、便利さだけでなく、ユーザーが迷わず、重くならず、必要な情報へたどり着ける設計を意識しましょう。
