SSRはなぜアクセシビリティに有利と言われるか

SSRは「アクセシビリティを実装しやすい」構造を持っている

SSRでアクセシビリティ(a11y)が有利になると言われるのは、SSRの方が丁寧に作られているからではありません。
ブラウザや支援技術が理解できる形のHTMLが最初から存在するためです。

アクセシビリティは「親切に作ること」ではなく、「機械が理解できる構造を提供すること」です。
スクリーンリーダー、キーボード操作、検索エンジンはすべてHTMLを解析して動作します。

このとき重要になるのが「最初に届くHTML」です。

スクリーンリーダーはJavaScriptを待たない

多くの支援技術はページを読み上げる際、まず受信したHTMLを解析します。
ここで内容が存在しなければ、何も読み上げられません。

SPAの初期レスポンスは次のようになります。

<div id="app"></div>

この時点では本文がありません。
JavaScriptが実行されるまで、スクリーンリーダーは内容を取得できません。

通信が遅い環境、CPU性能が低い端末、JavaScript制限環境では「空ページ」と認識されることがあります。

SSRでは意味構造を直接伝えられる

SSRでは最初のレスポンスに意味のあるHTMLが含まれます。

<main>
  <h1>お知らせ</h1>
  <article>
    <h2>メンテナンス情報</h2>
    <p>本日…</p>
  </article>
</main>

スクリーンリーダーは到着直後に構造を把握できます。

  • 見出しジャンプ
  • ランドマーク移動
  • 読み上げ順序

これらが正常に機能します。
これがSSRがアクセシビリティで有利になる最大の理由です。

キーボード操作との関係

アクセシビリティで重要なのはマウスを使わない操作です。
キーボード利用者は次の操作を多用します。

  • Tab移動
  • 見出し移動
  • フォーカス移動

SPAではJavaScriptがフォーカスを管理します。
画面更新時にフォーカス位置が失われる問題が起きやすくなります。

例:ルーター遷移

router.push("/about");

見た目はページ遷移ですが、実際はDOMの一部差し替えです。
ブラウザは「新しいページが表示された」と認識しません。
結果としてフォーカスが不適切な位置に残ります。

SSRではページロードが発生するため、フォーカスは自然に先頭へ移動します。

ARIAの役割が変わる

SPAではしばしば次の属性が必要になります。

  • aria-live
  • role="alert"
  • aria-busy

これは「画面が更新された」ことを支援技術に知らせるためです。
SPAはページ遷移が起きないため、状態変化を手動で通知する必要があります。

SSRではページロード自体が通知になります。
結果としてARIA依存が減ります。

実務で起きる典型的な問題

SPAでアクセシビリティ対応をすると、次の問題に直面します。

  • 読み上げが途中で止まる
  • 更新内容が伝わらない
  • 戻る操作で位置が分からない
  • モーダルが閉じられない

これらはUI設計の問題ではなく、「ページ遷移が存在しない」ことによる影響です。

SEOとの関係

検索エンジンもHTMLを解析します。
最近のクローラはJavaScriptを実行しますが、完全ではありません。

SSRでは

  • 見出し構造
  • 本文
  • リンク関係

が最初から取得できます。
アクセシビリティ対応とSEO対応が同時に改善する理由はここにあります。

ただしSSRなら自動でa11yが良くなるわけではない

重要な点として、SSRはアクセシビリティを保証しません。
間違ったHTMLを返せば当然問題は起きます。

例:

<div onclick="go()">ボタン</div>

これはSSRでもアクセシブルではありません。
ボタン要素を使う必要があります。

つまりSSRは「有利」ですが「自動対応」ではありません。

どう理解すればいいか

アクセシビリティはJavaScriptの問題ではなく、文書構造の問題です。
SSRは文書を先に提供し、SPAはアプリケーションを先に起動します。

支援技術が理解するのは文書です。
そのためSSRの方が自然に適合します。

SSRはアクセシビリティのための技術ではありません。
しかし、HTML中心のWeb本来の動作モデルに近いため、結果としてa11y対応を実装しやすくなります。

アクセシビリティ対応で苦労したとき、コード量ではなく「最初のHTMLに意味があるか」を確認することが、最も効果的な改善になることが多いです。