見出し画像

SEOで評価されるためのCSR・非同期読み込みYES/NOチャート【JavaScript SEO】

こんにちは!株式会社エイチームライフデザインでリードマーケター(主にコンテンツマーケ/SEO)をしている中澤 悠生です。

近年ではSEOでの上位表示を狙っているサイトでも、ReactやNext.js、vue.jsなどモダンなフレームワークが採用されているケースが増えてきています。

これらのフレームワークにはさまざまなメリットがある一方で、SEO観点ではデメリットになりえる要素も存在します。

私が特に注意が必要だと感じているのが、SPAやCSRと呼ばれるような、コンテンツがユーザー側で非同期読み込みされるページにおいて、検索エンジンがページ内容を正しく認識できるかどうかです

これらのページではURLへのリクエスト時にサーバーから返されるHTMLソース上にはコンテンツが含まれていないため、SEOでの上位表示もされづらくなる傾向があります。

「(非同期読み込みで)SEOのためにページ表示速度を改善したつもりが、コンテンツが認識されなくなって圏外に……」というようなことも起こり得るのです。

※最近のGooglebotはJavaScriptを実行できるようになっているので、
確実に順位がつかないというわけではありません。詳しくは本文で説明しています

とはいえ、あらゆるコンテンツを同期的に読み込まなければならないのかというと実はそうでもありません。例えばパーソナライズされたレコメンドのように、非同期読み込みをしてもSEO観点に悪影響のない要素も存在します。

このあたりの判断基準はやや複雑で、SEO担当同士や、エンジニア・デザイナーとの会話でも意見が割れがちなのではと思います。

そこで今回は、SEOを考慮した場合にページやコンポーネントを非同期読み込みにして良いのか、を判断するためのYES/NOチャートを作成しました。

SEO担当の方はもちろん、エンジニアやデザイナーの方にとっても参考になれば幸いです。

私がエンジニアではないのでエンジニアリング用語の使い方などが適切でないことがあるかも知れません。
もし内容に誤りがあればご指摘いただけますと幸いです…!

SEO観点での非同期読み込みチャートの説明

基本的には冒頭のYES/NOチャートに沿って判断していただければ問題ありませんが、より詳しく知りたい方に向けて各項目の説明をしていきます。

設問1. 非同期読み込みにしたいページは、検索で上位を狙いたいページか

まず最初に確認するべきことは「そもそもそのページは検索上位を狙いたいページなのか」です。

例えば、noindexを付与しているサイト内検索ページであったり、そもそもrobots.txtでDisallowに指定しているページなどは検索結果の上位を狙いたいページではありません。ユーザーログイン後のマイページなども該当しますね。

このような検索上位を狙う必要がないページであれば設問2へ。検索上位を狙いたいページなのであれば、設問3へお進みください。

設問2. 非同期読み込みにしたいページは、別ページのSEOに貢献するか

設問1ではページ自身が上位表示したいかどうかをチェックしましたが、設問2では「そのページが別のページのSEOに貢献するか」をチェックします。

SEOでは、そのページ自身は上位表示する必要がなくても、別ページの上位表示を下支えをするために重要なページが存在します。

ECサイトにおける商品の口コミ詳細ページなどを例とすると、イメージしやすいかなと思います。

商品の口コミ詳細ページは、そのページ自体では検索上位に表示されることは稀です(ロングテールでは表示されることもありますが)。しかし、口コミ詳細ページが複数あることが下支えとなって、「商品名 口コミ」や「商品名」などのキーワードでのSEO評価に貢献します。

マーケ以外の職能の方からは少しイメージしづらいかも知れませんが、会社概要ページやお問い合わせページなども該当します。Googleの「検索エンジン最適化(SEO)スターター ガイド」にも以下のような記述があり、「サイトの運営者が明確であることはSEOにとって重要である」とわかります。

評価の高いサイトは信頼できるサイトです。特定の分野で専門性と信頼性に対する評価を得られるようにしましょう。
サイトの運営者、コンテンツの提供者、サイトの目的を明確に示してください。

引用元:検索エンジン最適化(SEO)スターター ガイド

このように別ページのSEOに貢献するページでは、非同期読み込みの実装はリスクに繋がる可能性があります。

別ページのSEOに貢献するページなのであれば、設問3へ。もしこの設問もNOなのであれば、そのコンテンツは非同期読み込みで実装しても問題ありません

設問3. 非同期読み込みのコンテンツは、ページアクセスと同時に読み込まれるか

「非同期で読み込まれるコンテンツ」は、大きく以下の2つのパターンに分類できます。

  • A:ページアクセスと同時に読み込まれるパターン

  • B:ユーザーのインタラクション(クリックやスクロールなど)を起点に読み込まれるパターン

前者の「A:ページアクセスと同時に読み込まれるパターン」の場合は、検索エンジンからコンテンツが認識される可能性があります

対して後者の「B:ユーザーのインタラクション(クリックやスクロールなど)を起点に読み込まれるパターン」の場合は、検索エンジンがコンテンツを認識できない可能性があります

どちらも「可能性」と濁しているのは、実装方法によっては正しく認識されるケースがあったり、検索エンジン側のレンダリング待ちによって認識されないケースがあったりするためです。

詳しくはそれぞれ、次の設問で解説していきます。Aパターンの場合は設問6へ。Bパターンの場合は設問4へお進みください。

設問4. インタラクション起点で、CSSで表示を切り替えるだけなのか?HTMLが生成されるのか?

クリックやスクロールなどのユーザーインタラクションを起点としてコンテンツを読み込むケースについても、以下の2パターンに分けられます。

  • A:CSSで表示・非表示を切り替えるだけのパターン

  • B:HTMLを生成(もしくは置換)するパターン

前者の「A:CSSで表示・非表示を切り替えるだけのパターン」は、サーバーから返されたHTMLのソースコード上には、はじめからコンテンツが存在しており、インタラクションを起点にCSSで表示・非表示を切り替えているだけ、というケースを想定しています。

2023年10月のモバイルファーストインデックス完全移行後は、基本的にモバイル向けのGooglebotがWebサイトをクロールしています。また、モバイルファーストインデックス以降では、アコーディオン内のHTMLも認識するようになっています。

参考:https://www.suzukikenichi.com/blog/google-indexes-content-hidden-behind-tabs-or-accordions-after-mobile-first-indexing/

そのため「サーバーから返されるHTMLソース上にコンテンツが存在していてCSSで非表示になっているだけ」というコンテンツであれば、検索エンジンから認識されます。
このケースでは、動的なコンテンツとして実装を進めても問題ありません

一方で後者の「B:インタラクションを起点としてHTMLを生成(もしくは置換)するパターン」には注意が必要です。Googlebotはインタラクションを起点として生成されるHTMLを認識しません

GoogleのGary Illyesさんも、「JavaScriptの配列等に格納されていて、クリック起点で展開されるようなコンテンツはインデックスしない」と言っています。

ただしSEOを意識しているサイトだったとしても、インデックスされなくても問題がないコンテンツも存在します。こちらは次の設問5で解説します。

設問5. インタラクション起点でHTML生成されるコンテンツは、SEO観点で重要な要素か

HTMLが生成されるパターンだった場合は、その要素がSEO観点で重要な要素かどうかを判断します

例えば、ページのメインコンテンツであったり、SEOを意図した内部リンクなどですね。
ありがちな例で言うと、タブ切り替えボタンをクリックしたタイミングで、タブ内部のコンテンツが動的に読み込まれるケースなどが挙げられます。

これらの重要なコンテンツがインタラクション起点で生成されるサイトでは、そもそもメインコンテンツが認識されない検索エンジンが内部リンクを見つけられないなどの状態となり、正しいSEO評価を受けられなくなってしまいます。

SEO観点で意味のあるコンテンツの場合は、インタラクション起点で読み込まれる仕様にすることは絶対にNGです

一方でSEO的な意図を含まないコンテンツ、例えばユーザー行動を基にしたレコメンドなどは非同期読み込みでも問題ありません。これらのコンテンツはユーザーによって表示される内容が異なり、それをベースとして内部リンク構造を構築しているケースは恐らくないでしょう。

もし内部リンク構造がレコメンドに依存してしまっているのであれば、そもそもの内部リンク設計の見直しが必要です。

設問6. 非同期になっている箇所はページ全体かページの一部か

ページアクセスと同時に非同期コンテンツが読み込まれるサイトでは「ページ全体が非同期なのか」「ページの一部が非同期なのか」をチェックしましょう。

特に注意が必要なのは、ページ全体が非同期で読み込まれるケースです

Reactで実装されていたり、SPAサイトであったりする場合は、一般的な実装であればHTMLのソース上にコンテンツが含まれていません。

↓ こういう感じのHTMLが返ってくるケースです

<!DOCTYPE html>
<html lang="en">
<head>
  ~~~
</head>
<body>
  <div id="app"></div>
  <script>
    const root = createRoot(document.getElementById('app'));
    root.render(<h1>Hello, world</h1>);
  </script>
</body>
</html>

このようなJavaScriptベースのサイトでは、Googlebotがクロールキューに追加されたURLのHTMLを取得したあとに、さらにレンダリングキューに追加され、レンダリングの実行後にページのコンテンツが評価されます。

Google が JavaScript によって生成される実際のページ コンテンツを参照するには JavaScript を実行する必要があります。

robots meta タグまたはヘッダーによってページのインデックス登録が禁止されていなければ、Googlebot はすべてのページをレンダリングするためキューに入れます。ページはこのキューで数秒間(またはそれ以上)待機することがあります。Google のリソースに空きができると、ヘッドレスの Chromium がページをレンダリングして JavaScript を実行します。Googlebot はレンダリングされた HTML のリンクを再度解析し、見つかった URL をクロールするためキューに入れます。また、Google はレンダリングされた HTML を使用してページをインデックスに登録します。

引用元:Google が JavaScript を処理する仕組み

しかし、ページ数が多いサイトであったり、ひとつひとつのページの処理が重たい場合であったりすると、いつまで経ってもレンダリング処理が実行されないこともあります。

実際に弊社が運営しているNext.jsでCSRで構築されたサイトでも、Google側でのレンダリング処理が行われておらず、Search Console上では数ヶ月以上ずっとソフト404扱いになっているURLがありました

補足:
Search ConsoleのURL検査のライブテストでは、
JavaScriptのレンダリング後のHTMLが表示されるようです。

対してインデックス済みデータのほうは、
Google側でのJavaScriptのレンダリング前だった場合はそのままレンダリング前のHTMLが表示され、
レンダリング後だった場合にはレンダリング後のHTMLが表示されます。

レンダリング処理が終わればページは正しく評価されるケースも多いのですが、一般的なHTMLで構築されたページよりも評価がされるまでの期間が長くなってしまったり、数ヶ月以上も評価されないこともあります。

そのため、ページ全体が非同期で読み込まれるような仕様での実装は基本的に避けましょう

設問7. 非同期読み込みされるコンテンツはSEO観点で重要な要素か

ページ内のコンテンツの一部が非同期で読み込まれるケースでは、その要素がSEO観点で重要な要素であるかどうか、から判断します。

考え方は設問5と同じで、ページのメインコンテンツであったり、SEOを意図した内部リンクなどが、SEO観点で重要な要素に該当します。

設問6でも触れたように、ページ表示と同時に読み込まれるのであれば、検索エンジン側のレンダリング処理が終わったあとで該当のコンテンツが認識されます。逆を言うとレンダリング処理が終わるまでは非同期コンテンツの箇所が認識されないため、「内部リンクを設置したのに、何ヶ月経っても認識されない」ということが起こり得るのです。

またここでも、ユーザー行動を基にしたレコメンドなど、SEO観点では重要ではない要素の場合は非同期読み込みで実装しても問題ありません。

まとめ

ページ表示速度やユーザビリティを考慮して、非同期読み込みを実装したいケースは頻繁にあるかと思います。しかし本文でも触れたように、実装対象のコンテンツや実装方法によってはSEOに悪影響を及ぼしてしまうこともあります。

今回ご紹介したYES/NOチャートを参考に、ページの設計に活かしていただけると幸いです。

エイチームライフデザインのnoteでは、コンテンツマーケ・アドマーケ・ブランディングデザインなどのノウハウや社内事例を紹介していますので、ぜひフォローやスキをいただけると幸いです(一緒に働ける仲間も募集しています🎉)