SPAのSEOって、なんでこんなに面倒なんだっけ?
正直、SPA(シングルページアプリケーション)のSEO対策って、考えるたびに「うーん」ってなるんですよね。ユーザー体験はすごく良いんですよ、ネイティブアプリみたいにサクサク動いて。 ページ遷移で画面が真っ白になることもないし、操作性は抜群。 だから開発者としては作りたい。でも、SEO担当者からすると「ちょっと待って!」ってなる。このジレンマ、結構あるあるじゃないですかね。
じゃあ、何がそんなに問題なのか。一言でいうと、検索エンジンのクローラーが「からっぽのHTML」を見ちゃう可能性があるからなんです。 SPAって、最初に読み込むのは最小限のHTMLと、あとは大量のJavaScriptファイル。 実際に画面に表示される内容は、ブラウザがJavaScriptを実行して、後から動的に作り出す仕組みなんですよね。 これをクライアントサイドレンダリング(CSR)って言います。 でも、昔のクローラーはJavaScriptを実行するのが苦手で、ただの枠組みしか見えなかった。結果、「このページ、中身ないじゃん」って判断されて、インデックスされない…なんて悲劇が起きていたわけです。
もちろん、最近のGooglebotはめちゃくちゃ賢くなってて、JavaScriptをかなり高い精度で実行(レンダリング)してくれるようになりました。 AIも使って、どうやってコードが動くか予測までしてるらしいです。 だから「もうCSRのままでも大丈夫じゃん?」って思う気持ちも、すごくわかります。GoogleのMartin Splitt氏も「ケースバイケース」とは言っていますしね。 でも、やっぱり100%完璧じゃない。 複雑なJavaScriptだとレンダリングに失敗したり、処理が後回しにされてインデックス登録が遅れたりするリスクは依然として残ってるんです。 実際、SSRを導入したSPAサイトのインデックス登録率が83.2%なのに対して、CSRだけだと48.5%に留まるというデータもあるみたいですし…。 ちょっと、この差は無視できないですよね。
じゃあ、どうすればいいの?解決策はこの3つ
結局のところ、「クローラーに優しく、かつユーザー体験も損なわない」という良いとこ取りを目指すのが現実的な着地点になります。そのための代表的な手法が、主に3つあります。サーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、そしてダイナミックレンダリングです。 Next.jsやNuxt.jsといったモダンなフレームワークは、これらの実装を簡単にしてくれることで人気があります。
| 手法 | 仕組み | 個人的な感想・使いどころ |
|---|---|---|
| サーバーサイドレンダリング (SSR) | ユーザーがページにアクセスするたびに、サーバー側でHTMLを生成して返す。 クローラーは最初から完成品のHTMLを受け取れる。 | まさに王道。SEO効果は一番確実だと思います。 ユーザーごとに表示内容が変わるマイページや、頻繁に更新されるメディアサイトなんかに向いてますね。 ただ、サーバーの負荷は高めになるし、実装もちょっと複雑になりがち。 |
| 静的サイト生成 (SSG) | ビルド時(サイトを公開する前)に、あらかじめ全ページのHTMLを生成しておく。 ユーザーやクローラーは、すでに出来上がっている静的ファイルにアクセスするだけ。 | 表示速度は最速。 だって、ただのHTMLファイルですから。ブログや製品紹介ページ、コーポレートサイトみたいに、内容があまり頻繁に変わらないサイトならこれが最強かも。更新のたびにビルドし直す手間はあるけど、それを補って余りあるメリットがあります。 |
| ダイナミックレンダリング | アクセスしてきたのがユーザーかクローラーかを見分けて、出し分ける方法。 ユーザーには通常のSPA(CSR)を、クローラーには別途用意したHTML(SSRやプリレンダリングしたもの)を見せる。 | 既存のSPAに後からSEO対策をしたい、みたいな緊急避難的なケースではアリかも。でも、正直言ってこれは「クローキング(cloaking)」、つまりGoogleが嫌う「見せかけ行為」と紙一重。 同じコンテンツを見せている限りは問題ないとされていますが、管理が煩雑になるし、個人的にはあまり選びたくない選択肢かな、と思います。 |
あと、大事なことを忘れていました。Google以外の検索エンジンです。例えばBing。BingbotもJavaScriptをレンダリングできるとは言っていますが、Googleほど強力じゃない可能性があります。 Bingの公式ブログでは、確実なクロールとインデックスのためには、サーバー側で静的なHTMLを出力することを推奨しています。 つまり、やっぱりSSRやSSGが無難、ということですね。世界中のユーザーを相手にするなら、Googleだけ見ていればいいってわけじゃないですから。
実装でハマりがちな落とし穴
よし、じゃあNext.jsでSSR/SSGを実装しよう!となっても、まだ安心はできません。SPA特有の「うっかりミス」がいくつかあります。
- メタタグの動的管理: SPAは単一のページなので、何もしないと全ページで`title`や`description`が同じになっちゃいます。ちゃんとページごとにユニークなメタ情報を``内に動的に設定してあげないと、SEO的に大問題です。
- 適切なURL構造: `#`(ハッシュ)を使ったルーティングは避けるべきです。 `/products/123` のような、ちゃんとしたパス形式のURLを使いましょう。 これで各ページが独立した存在として認識され、クロールされやすくなります。
- 内部リンクは``で: 見た目はボタンだけど、実はJavaScriptの`onClick`イベントでページ遷移させてる…みたいな実装、やりがちですよね。クローラーは``タグの`href`属性を辿ってサイト内を巡回するので、基本的なリンクは必ず``タグで実装することが鉄則です。
これからのSPA SEO:INPを意識する
最近、Core Web Vitalsの指標として「INP(Interaction to Next Paint)」がFIDに代わって導入されました。 これは、ユーザーがボタンをクリックしたり、入力したりしてから、画面に次の変化が起こるまでの応答性を測る指標です。 要するに、サイトの「サクサク感」を数値化したものですね。
で、これがなぜSPAに関係あるかというと、SPAはJavaScriptの処理が重くなりがちだからです。 特に初期ロード後、大量のJavaScriptがバックグラウンドで動いていると、ユーザーのアクションへの反応が遅れ、INPのスコアが悪化する可能性があります。 GoogleはINPの目標値を200ミリ秒以下としています。 これを超えるとユーザー体験が悪いと判断され、SEO評価にも影響しかねません。
だから、これからのSPA開発では、SSR/SSGで初期表示速度を上げるだけでなく、クライアント側でのJavaScript実行を最適化してINPを改善することも、SEOの重要な一部になってくるはずです。不要なJavaScriptを削ったり、重い処理を分割したり、といった地道な作業が求められますね。
まとめ:結局、バランスが大事
SPAのSEOは、「これさえやればOK」という銀の弾丸はありません。でも、基本方針ははっきりしています。「クローラーが理解できるHTMLを、できるだけ早く提供すること」。そのためにSSRやSSGといった技術を使いこなす。 そして、ユーザー体験の指標であるCore Web Vitals、特にINPも意識して、JavaScriptのパフォーマンスを最適化する。 この両輪で考えていくのが、今のところの最適解なんだろうな、と思っています。
正直、学習コストは高いし、考えることも多いです。 でも、その分、うまく実装できたときのサクサク感と、検索流入が両立できたときの喜びは大きいですよね。あなたのプロジェクトでは、どんなレンダリング戦略を選びましたか?あるいは、どんなことで悩んでいますか?もしよければ、ぜひ聞かせてください。
