JavaScriptで描画したページはいつ読まれるのか ── レンダリングキューの仕組みと、確認する14項目
JavaScriptで描画したページはいつ読まれるのか ── レンダリングキューの仕組みと、確認する14項目
01 何が起きたか — JavaScriptで描画したページは、いつ読まれるのか
出典
本記事の公式情報はGoogle Search Central「JavaScript SEO basics(訳: JavaScriptのSEOの基本)」(最終更新2026年3月4日・UTC)を主な出典としています。当サイトが独自に発表した内容ではありません。
Googlebotは3段階に分けてページを処理する
フロントエンドのフレームワークで生成しているページや、一覧の一部だけをJavaScriptで後から埋めているページを持つサイトは、今も少なくありません。こうしたページに対して、Googleは「クロール」「レンダリング」「インデックス登録」という3つの工程を経て処理を進めています。まずGooglebotがURLを取得し、返ってきたHTTPステータスコードが200であれば、そのページはレンダリングを待つ列に送られます。公式ドキュメントはこの流れを次のように説明しています。
"All pages with a 200 HTTP status code are sent to the rendering queue."
(訳: ステータスコード200を返すすべてのページは、レンダリングキュー(レンダリングの待ち行列)に送られます。)
ここで見落とされやすいのは、クロールされた瞬間と、ページの中身がGoogleに把握される瞬間は、別のタイミングだという点です。取得した生のHTMLの中にJavaScriptで後から挿入する予定の文章や画像がまだ含まれていなくても、それ自体は異常ではありません。問題になるのは、その先のレンダリング工程が実際に完了しているかどうかです。
レンダリングには「数秒」以上かかることがある
レンダリングキューに入ったページが、いつ実際に描画されるかについて、公式ドキュメントは次のように述べています。
"The page may stay on this queue for a few seconds, but it can take longer than that. Once Google's resources allow, a headless Chromium renders the page and executes the JavaScript."
(訳: ページはこの待ち行列に数秒間とどまることもありますが、それより長くかかることもあります。Googleのリソースに余裕ができ次第、ヘッドレス版のChromiumがページを描画し、JavaScriptを実行します。)
「数秒」という表現は最短の目安であり、上限の時間は明記されていません。Googleのリソースの空き具合に依存するという一文が、この工程の性質をそのまま表しています。レンダリングが完了して初めて、Googleはそのページに実際にどんな本文・見出し・画像が含まれているかを把握し、そこから先のインデックス登録の判断に進みます。クロールの直後に取得できる生のHTMLと、レンダリングを経たあとのHTMLは、内容が異なりうる別のものとして扱う必要があります。
3つの工程で、それぞれ何が確認できるか
ここまでの流れを、確認の観点で整理し直すと次の表のようになります。段階ごとに「今どちらの状態を見ているか」を先に押さえておくと、あとの章のチェックリストが扱っている内容もつかみやすくなります。
| 段階 | Googleが行うこと | この段階で確認できること |
|---|---|---|
| ①クロール | URLを取得し、HTTPステータスコードを確認する | ステータスコードが200か・生のHTMLに何が含まれるか |
| ②レンダリング | ヘッドレスChromiumでJavaScriptを実行し、ページを描画する | 実行後のDOMに、本文・タイトル・画像が反映されているか |
| ③インデックス登録 | 描画結果をもとに、ページの内容を検索用に登録する | Search Consoleで登録状況とレンダリング結果を確認できる |

02 なぜ・背景 — JavaScriptがSEOの課題になり続ける理由
サーバー側で作るHTMLと、ブラウザの中で作るHTMLの違い
サーバー側であらかじめ本文まで組み立てたHTMLを返す作り方(サーバーサイドレンダリング)と、ブラウザに最小限のHTMLだけを渡し、その後JavaScriptが本文を組み立てる作り方(クライアントサイドレンダリング)とでは、Googlebotから見た「取得直後の状態」がまったく違います。前者は取得した瞬間から本文が読める状態にありますが、後者は取得した瞬間には本文がまだ存在せず、レンダリング工程を経て初めて内容が現れます。どちらの作り方を選ぶか自体は自由ですが、後者を選んだ場合はレンダリング工程が正しく完了しているかを、自分で確認する責任が生じます。
近年は、最初の描画だけサーバー側で行い、その後の操作をクライアント側のJavaScriptに引き継ぐハイブリッドな構成(ハイドレーション)も広く使われています。この構成では、初回のHTMLに本文が含まれているため、レンダリング待ちの影響を受けにくいという利点があります。一方で、実装によっては特定の要素だけがクライアント側の処理を待たないと現れない、という部分的な問題が残ることもあります。
「表示されている」ことと「クロールされている」ことは別
ブラウザで開いたときに正しく表示されているページでも、それがそのままGoogleに正しく読まれている証拠にはなりません。表示は、閲覧者のブラウザが持つJavaScriptエンジンとネットワーク環境の中で完結する現象であるのに対し、クロールとレンダリングはGoogle側のインフラの都合で進む、別の処理だからです。この違いが最もはっきり表れるのが、クライアントサイドレンダリングを採用したサイトで、存在しないURLにアクセスされたときの挙動です。公式ドキュメントは次のように述べています。
"To avoid soft 404 errors when using client-side rendering and routing, use one of the following strategies."
(訳: クライアントサイドレンダリングとルーティングを使用する場合にsoft 404エラーを避けるには、次のいずれかの戦略を使ってください。)
注意
クライアントサイドレンダリングのアプリでは、サーバーはどのURLに対してもまず同じ「空の器」となるHTMLをステータスコード200で返すことが多くあります。存在しないページに対しても200が返ってしまうと、Googleはそのページを「存在する正常なページ」として扱ってしまいます。これがsoft 404と呼ばれる状態で、本来404であるべきページが検索結果に残り続ける原因になります。
この問題への対処は、次の03章と04章で扱う型別の中で、具体的な手順として整理します。
03 この記事で出てくる用語
クロールキューとレンダリングキュー
用語
crawl queue(クロールキュー): Googlebotがまだ取得していないURLが並ぶ待ち行列です。サイトの更新頻度やクロール予算に応じて、取得される順番と間隔が変わります。
用語
rendering queue(レンダリングキュー): ステータスコード200で取得されたページが、ヘッドレスChromiumによる描画を待つ行列です。クロールキューとは別の行列であり、ここで数秒からそれ以上の遅延が生じます。
Soft 404(ソフト404)
用語
Soft 404: 存在しない、または内容が空のページに対して、サーバーがHTTPステータスコード200(正常)を返してしまっている状態です。ページの見た目には「見つかりません」といった文言が表示されていても、ステータスコードが200のままだと、Googleはそのページを正常なページとして扱う可能性があります。対処法はrobotsメタタグとXロボットタグに関する公式ドキュメントで説明されているnoindexの指定と合わせて確認します。
Shadow DOMとWeb Components
Web ComponentsやShadow DOMを使って部品化されたUIを組んでいるサイトも増えています。この構成には、インデックス登録の観点で見落としやすい注意点があります。
注意
公式ドキュメントは次のように述べています。
"Google can only see content that's visible in the rendered HTML."
(訳: Googleは、レンダリングされたHTMLの中で実際に見える状態にあるコンテンツしか見ることができません。)
Shadow DOMの中に置いた文章であっても、レンダリング結果として表示状態にあれば読まれますが、CSSで非表示にしている、あるいは特定の操作をしないと展開されない部分は、レンダリング結果にも現れないため読まれません。「コード上には存在するが、描画結果には現れない」状態を作らないことが、Web Componentsを使う際の基本になります。
04 型別 — 適用範囲・確認していないこと・手順
🅰 適用範囲 — この記事が関係するサイト
この記事が関係するのは、ページの主要な本文・タイトル・見出し・画像のいずれかを、JavaScriptの実行後に初めて表示させている構成のサイトです。サーバー側があらかじめ本文まで含めたHTMLを返しているサイトでは、この記事で扱う遅延やsoft 404の問題はそもそも発生しません。逆に、フロントエンドのフレームワークで一覧や詳細ページを構築している場合、あるいは特定のウィジェットだけを非同期に読み込んでいる場合は、この記事の対象になります。
🅱 この記事が確認していないこと
確認していないことも明確にしておきます。第一に、特定のフレームワーク(React・Vue・Angularなど)ごとの実装手順は、製品やバージョンによって異なるため、この記事では扱いません。第二に、レンダリングにかかる具体的な秒数の上限は、確認した公式情報の範囲では「数秒、あるいはそれ以上」としか説明されておらず、サイトごとに実際にかかる時間は公開されていません。第三に、レンダリング済みの内容が実際の検索順位にどう影響するかは、この記事の範囲では扱わず、あくまで「読まれているかどうか」の確認に絞っています。
🅲 手順 — 確認から対処までの4段階
作業は次の順番で進めます。第一に、対象ページの生のHTML(レンダリング前)を取得し、本文がすでに含まれているかを確認します。第二に、Search ConsoleのURL検査ツールで、レンダリング後のHTMLとスクリーンショットを取得します。第三に、生のHTMLとレンダリング後のHTMLを見比べ、タイトル・見出し・本文・canonicalタグに差がないかを確認します。第四に、存在しないURLへのアクセス時に返るステータスコードを確認し、soft 404になっていないかを見ます。この4段階のうち、第三の「差がないか」の確認が最も見落とされやすい工程です。
注意
canonicalタグについて、公式ドキュメントは次のように明記しています。
"You shouldn't use JavaScript to change the canonical URL to something else than the URL you specified as the canonical URL in the original HTML."
(訳: 元のHTMLでcanonical URLとして指定したURLとは別の値に、JavaScriptでcanonicalURLを変更してはいけません。)
JavaScriptの実行タイミングによってcanonicalタグの値が書き換わっているサイトは、意図せずこの規則に反していることがあります。03章のチェックリストと合わせて確認してください。
ルーティングの実装方法についても、公式ドキュメントは明確な方針を示しています。
"Use the History API to implement routing between different views of your web app. To ensure that Googlebot can parse and extract your URLs, don't use fragments to load different page content."
(訳: Webアプリの異なる画面間のルーティングを実装するには、History APIを使ってください。GooglebotがURLを正しく解析・抽出できるようにするため、フラグメント識別子を使って異なるページの内容を読み込ませないでください。)
URLの末尾に付く#以降の値(フラグメント識別子)だけでページの内容を切り替える実装は、URLごとに個別のページとしてクロールされない可能性があります。History APIを使い、URL自体を切り替える実装にすることが推奨されています。
05 自分のサイトで確認するチェックリスト
3つの観点に分けて確認する
ここまでの内容を、今日から手を動かせる作業に翻訳しました。観点は、レンダリング前後の内容の一致、soft 404への対処、URLとルーティングの実装の3つに分かれます。チェックの状態はブラウザ内にのみ保存され、サーバーには送信されません。
実務のヒント
レンダリング前の生のHTMLは、ブラウザの開発者ツールを開かなくても、コマンドラインが使える環境であればcurlコマンドで対象URLを取得するだけで確認できます。取得した結果に、見出しタグ(<h2>など)や本文の一部が含まれているかを検索するだけで、JavaScriptに依存せずに本文が届いているかの目安になります。
- 対象ページのURLを1つ選び、レンダリングなしで生のHTMLを取得する(
curlやブラウザの「ページのソースを表示」) - 取得した生のHTMLに、本来表示したい見出し・本文・商品名などの文章が含まれているか確認する
- ブラウザの開発者ツールでレンダリング後のDOMを開き、生のHTMLと内容が一致するか見比べる
- Search ConsoleのURL検査ツールで対象URLをテストし、取得したHTMLとレンダリング後のスクリーンショットを確認する
- 4で取得したスクリーンショットに、本来表示されるべき本文・画像・価格などが写っているか確認する
- titleタグとmeta descriptionが、JavaScriptによる書き換え後も意図した内容のまま保たれているか確認する
- canonicalタグの値が、ページ読み込み後にJavaScriptで元の値から変更されていないか確認する
- 存在しないURLにアクセスした際、実際のHTTPステータスコードが404または410を返しているか確認する
- 8で正しいステータスコードを返せない構成の場合、
noindexを指定したrobotsメタタグが出力されているか確認する - Shadow DOMを使っている箇所があれば、開発者ツールでshadow rootの中身を開き、非表示のまま隠れているコンテンツがないか確認する
- URLの末尾にフラグメント識別子(
#)だけで内容を切り替えている画面がないか確認する - CSS・JSファイルのURLに、内容変更のたびにファイル名(ハッシュ)が変わる仕組みが入っているか確認する
- Search Consoleの「ページのインデックス登録」レポートで、対象URLの登録状況とクロール日時を確認する
- 確認した日時・URL・レンダリング結果の一致または不一致を記録に残す
14項目の内訳と、かかる時間の目安
最初の5項目は生HTMLとレンダリング後の内容の一致確認、6番目から9番目はタイトル・canonical・ステータスコードの確認、10番目と11番目はShadow DOMとルーティングの確認、12番目から14番目はキャッシュとSearch Consoleでの確認と記録です。すべてに目を通す時間の目安はページ1件あたり15分程度です。サイト内でJavaScriptに依存する画面が複数ある場合は、画面の種類ごとに1回ずつ確認すれば、ページ単位で毎回繰り返す必要はありません。
06 3つの対応方針を比較する — サーバー側レンダリング・動的レンダリング・そのまま
動的レンダリングは、もう推奨されていない
クライアントサイドレンダリングの内容をGoogleに正しく読ませる方法として、以前は「動的レンダリング(Dynamic Rendering)」という手法が案内されていました。ボットからのアクセスを検出し、ボット向けにはサーバー側で描画済みの静的HTMLを、通常の利用者向けにはそのままクライアント側で描画したページを出し分ける仕組みです。しかし、この手法について、公式ドキュメントは現在こう明記しています。
"Dynamic rendering is a workaround and not a recommended solution."
(訳: 動的レンダリングは回避策であり、推奨される解決策ではありません。)
代わりに公式ドキュメントが挙げているのは、サーバー側レンダリング(server-side rendering)、静的レンダリング(static rendering)、ハイドレーション(hydration)の3つです。いずれも、ボットと利用者に同じHTMLを提供する構成である点が共通しています。動的レンダリングのように出し分けを行う構成は、実装の複雑さに見合うだけの利点が薄れてきている、というのが現在の位置づけです。
| 方針 | 内容 | 向いているケース |
|---|---|---|
| サーバー側 レンダリング | サーバー側で本文まで組み立てたHTMLを都度生成して返す | 新規に構築するサイトや、大規模な作り直しが可能な場合 |
| 静的レンダリング +ハイドレーション | あらかじめ生成した静的HTMLを返し、ブラウザ側で操作性を後付けする | 更新頻度が低いページが中心で、初期表示速度も重視する場合 |
| そのまま (対応なし) | クライアントサイドレンダリングのままレンダリングキューに任せる | 更新頻度が高くないページ数の少ないサイトで、遅延の許容度が高い場合 |

どの方針を選んでも、04章で確認した「生のHTMLとレンダリング後のHTMLの内容が一致しているか」という確認作業自体は変わりません。方針を変えることは、確認作業を省略できる理由にはなりません。方針を切り替えた直後こそ、05章のチェックリストを一度すべて通しておくことをおすすめします。

07 当サイトで確認したこと
確認結果 — 当サイトはサーバー側で本文まで組み立てている
この記事を書くにあたり、当サイトの実装状況も確認しました。seo_articleの記事ページを、JavaScriptを実行しない状態で取得し、本文中の見出しタグ(<h2>)がいくつ含まれているかを数えたところ、レンダリング前の時点ですでに13個の見出しが取得できました。読み込んでいる外部スクリプトの一覧を確認しても、目次生成やチェックリストの動作に使う補助的なスクリプトが並んでいるだけで、本文そのものをJavaScriptで組み立てる仕組みは使われていません。
この確認方法自体は、他のサイトでも同じように使えます。対象URLをcurlで取得し、本来表示されるべき見出しや本文の一部が、JavaScriptを実行しない時点ですでに含まれているかを検索するだけで、レンダリング工程への依存度がおおまかに分かります。ただし、「生のHTMLに含まれている」ことと「レンダリング後の内容と一致している」ことは別です。当サイトのように依存度が低い構成であっても、05章のチェックリストに沿って、canonicalタグやステータスコードまで含めて確認する価値があります。
08 このテーマの、これまで
動的レンダリングという回避策が生まれ、役目を終えるまで
JavaScriptで生成したコンテンツをGoogleに正しく読ませるという課題自体は、フロントエンドのフレームワークが広く使われ始めた時期から一貫して存在していました。その解決策として一時期案内されていたのが「動的レンダリング」でした。ボットとその他の利用者にサーバー側で振る舞いを出し分けるこの方法は、当時としては現実的な回避策でしたが、公式ドキュメントの説明にある通り、あくまで「回避策であり、長期的な解決策ではない」という位置づけでした。
その後、サーバー側レンダリングやハイドレーションを実現するための仕組みが各フレームワークで整備されるにつれて、ボットとその他の利用者に別々のHTMLを出し分ける必然性は薄れていきました。公式ドキュメントの動的レンダリングに関するページ自体が、2025年12月10日(UTC)の時点でも、冒頭から明確に非推奨の立場を取り続けています。仕組みそのものが古くなったのではなく、同じ目的をより単純な構成で達成できる選択肢が増えたことが、位置づけを変えた理由だと考えられます。
「表示されている」の確認方法も、変わり続けている
レンダリング結果の確認手段も、時期によって変化しています。現在はSearch ConsoleのURL検査ツールで、取得したHTMLとレンダリング後のスクリーンショットの両方を、同じ画面から確認できます。以前は、レンダリング結果を確認する手段がより限られていた時期もありました。確認手段が整備されるほど、「動いているように見える」という主観的な印象ではなく、実際に取得した結果を見て判断する姿勢が取りやすくなっています。
当サイトが繰り返し確認している「書いてあることと、動いていることは別」という論点は、JavaScriptのレンダリングにもそのまま当てはまります。ステータスコードが200で返ってくることは、ページが存在することの証明であって、本文が実際にGoogleへ届いていることの証明ではありません。この違いは、出力の仕組みが正しく組まれているかを、実際のレンダリング結果まで確認して初めて分かるという点で、日付やタイトルの表示が仕組みどおりに出力されているかを確認した回(archives/128)とも共通しています。
画像やリンクにも、同じ確認の型が当てはまる
「取得できる状態にある」ことと「実際に読まれている」ことの違いは、画像の配信状況を確認した回でも扱っています。公開中の記事が参照する画像のうち、一部が本来の配置場所に届いていなかった事例では、記事のページ自体はステータスコード200で表示されていても、画像だけが読み込めない状態になっていました(archives/133)。ページ全体が正常に見えることと、その中の個々の要素が正しく届いていることは、別々に確認する必要がある、という点は本記事のレンダリング確認とも重なります。
また、「測定中」と書かれた状態のまま確認が止まってしまうと、実際には誰も測っていない状態が続いてしまうという指摘も、当サイトの別の回で扱っています(archives/135)。レンダリングの確認も同じで、一度チェックリストを通したら、実装を変更するたびに確認をやり直す運用にしておくことが、確認を形だけのものにしないための前提になります。
Shadow DOMの中身がレンダリング結果に現れるかどうかという確認は、ページの構造をどこまで見に行くかという点で、内部リンクの飛び先が実際に公開中の記事を指しているかを確認する作業とも近い性質を持っています。見た目の上では正常に見えるページの内部に、実際には反映されていない部分が残っているという構図は、レンダリングの確認・内部リンクの確認のどちらでも起こりえます。canonicalタグの扱いを整理した回や、Core Web Vitalsとクロールの関係を整理した回も、同じ「表示と処理は別」という前提の上に成り立っています。
現在の貴方のIPアドレス
このサイトで書いている人
WEBサイト