JavaScript SEO 實測:Google、Bing、Yandex 到底怎麼處理 JS 頁面

2024-05-04|技術 SEO|閱讀時長:4 分鐘

JavaScript 不是 SEO 的敵人。真正麻煩的地方,在於很多團隊會不自覺地假設:只要頁面在瀏覽器裡看起來沒問題,搜尋引擎也一定看得到同樣內容。這件事其實沒那麼穩。

這篇文章不是只談原理,而是回到一個很直接的實驗:做一個幾乎把核心內容都交給 JavaScript 客端渲染的頁面,然後觀察 Google、Bing、Yandex 分別怎麼抓、怎麼顯示、多久才更新。

如果你平常在做 React、Vue、Next.js、Nuxt,或任何以 CSR 為主的前端架構,這個問題其實非常貼身。若你想先確認搜尋引擎實際拿到的是什麼,SEO Analyzer 可以先幫你檢查 initial HTML 和技術訊號有沒有缺關鍵東西。

先講最重要的背景:兩階段索引

Google 對這類 JS 頁面,常常不是一次做完,而是分兩輪:

  1. 先抓 initial HTML,做第一輪索引。
  2. 等到渲染資源輪到這頁,再執行 JavaScript,重新看最終 DOM。

這個差別很要命。因為如果你的核心內容只在 JS 執行後才出現,它就不會出現在第一輪。

Google 兩階段索引流程圖,顯示 crawl、初次 index 與後續 render 的關係

這也是為什麼有些頁面剛進索引時,title 或 snippet 看起來很怪,過幾天才慢慢修正。

這次實驗頁面怎麼設計

測試頁刻意做得很極端:

  • 初始 HTML 幾乎是空的
  • titleH1、meta description、主體文字都靠 JS 塞進去
  • 內容透過 AJAX 載入
  • Article schema 也用 JS 注入

換句話說,如果搜尋引擎不執行 JavaScript,它能讀到的有用內容非常少。

1$(document).ready(function () { 2 $.ajax({ 3 url: '/api/get-article-data', 4 success: function(data) { 5 $('title').text(data.title); 6 $('h1#main-title').text(data.h1); 7 $('meta[name="description"]').attr('content', data.description); 8 $('#article-content').html(data.body); 9 10 var script = document.createElement('script'); 11 script.type = 'application/ld+json'; 12 script.text = JSON.stringify(data.schemaData); 13 document.head.appendChild(script); 14 } 15 }); 16});

故意把初始 HTML 和最終 DOM 做得差很多,這樣只要看搜尋結果變化,就能很清楚知道搜尋引擎到底有沒有走到第二輪。

Google 的工具看得到什麼

先不急著看 SERP,本地工具與官方工具本身就已經給了不少線索。這個案例裡,Google 的 Rich Results Test 可以正常產生最終 DOM,也能抓到 JavaScript 後注入的資料。

Google Rich Results Test 產生的渲染 DOM,畫面中可看到由 JavaScript 補上的 title 與 description

這代表 Google 在技術上是看得懂這頁的。但「看得懂」不代表「馬上就會反映到索引與 SERP」。

第一輪結果:一開始 SERP 顯示了什麼

在提交後幾個小時內,Google、Bing、Yandex 都已經能搜到這頁。但顯示出來的標題與描述,依然是初始 HTML 裡那點內容,不是 JS 渲染後的版本。

多個搜尋引擎的初期 SERP 片段,內容主要來自基礎 HTML 而非 JavaScript 渲染結果

這其實就是兩階段索引最直觀的樣子。頁面已經進索引了,但還不是你希望搜尋引擎最終理解的那個版本。

如果你做的是下列情境,這種延遲尤其麻煩:

  • 新上線 landing page
  • 新聞或時效型內容
  • 需要快速更新 title 與 description 的頁面
  • 很依賴早期收錄速度的專案

第二輪:Google 最後還是會追上,但不快

幾天之後,再用 site: 搜尋時,已經看得到原本只存在於 JS 渲染後的文字。這代表 Google 確實把第二輪渲染結果帶進索引裡了。

Google 的 site 搜尋結果中,已經出現原本只在 JavaScript 執行後才存在的內容片段

實務上這代表什麼?代表 Google 確實能處理 AJAX 加載、客端渲染的內容,但它不一定會立刻做。

對某些站來說,慢幾天沒差。對另外一些站來說,這就是風險。

Bing 和 Yandex:差距在這裡變得很明顯

同一段期間裡,Bing 和 Yandex 顯然更依賴 initial HTML。它們沒有像 Google 一樣明顯地跟上最終渲染內容。

這件事很重要,因為很多團隊其實只用 Google 的能力來假設所有搜尋引擎。真實世界不是這樣。不同引擎對 JS 的容忍度與處理能力,差異還是很大。

後備做法:Dynamic Rendering

接著又試了一個常見折衷方案:dynamic rendering。

  • 一般使用者拿到正常的 JS 頁面
  • crawler 則拿到已經預先渲染好的 HTML

Dynamic rendering 示意圖:瀏覽器接收 HTML 加 JavaScript,而 crawler 直接取得預先渲染好的靜態 HTML

啟用之後,Yandex 的 snippet 就跟著更新了,開始採用預渲染版本的內容。

啟用 dynamic rendering 後,Yandex 以預先渲染的內容更新了搜尋結果片段

這不代表 dynamic rendering 是所有新專案的最佳解。它只是很清楚地說明一件事:只要搜尋引擎早點拿到可直接閱讀的 HTML,問題通常就會少很多。

這個實驗真正說明了什麼

1. Google 會渲染 JS,但這不等於 SEO 沒風險

最常見的誤解是:「Google 反正會 render JS,所以放哪都沒差。」

實際上不是這樣。因為:

  • 渲染有排隊
  • 索引更新有延遲
  • 每頁不一定都以同樣速度處理
  • initial HTML 沒有的內容,SEO 即時性就會變差

2. Initial HTML 還是最穩的保險

如果頁面對 SEO 很重要,最好讓這些元素一開始就出現在 HTML 裡:

  • <title>
  • meta description
  • H1
  • 主要文字內容
  • 重要導覽與內鏈
  • 關鍵結構化資料

這樣不只 Google 比較穩,其他搜尋引擎也比較不容易出事。

3. SSR 與 SSG 還是更穩的做法

如果技術條件允許,SSR 或 SSG 依然是做 SEO 關鍵頁面時比較放心的方案。不是說 CSR 完全不能用,而是你不該把 title、description 與核心內容都交給一個可能延遲的第二輪渲染。

4. Dynamic Rendering 比較像過渡方案

對舊系統、歷史包袱重的專案,它很有用。但對新專案來說,它通常不是最乾淨的終點。因為它會增加維運複雜度,也要更小心避免 bot 版與 user 版差太多。

給 SEO 與前端團隊的實務建議

把這次實驗濃縮成工作原則,大概就是:

  1. 不要把 SEO 核心內容完全押在 CSR 上。
  2. 永遠確認 crawler 實際拿到的 HTML。
  3. 如果收錄速度很重要,優先考慮 SSR 或 SSG。
  4. 把 CSR 留給互動層,不要留給語意主體。
  5. 只有在現實架構真的卡住時,再考慮 dynamic rendering。

在上線前的檢查流程裡,可以先用 SEO Analyzer 看 initial HTML 有沒有把關鍵東西送出去,再用 Meta-Tag Generator 把 snippet 相關訊號補穩。

結語

這個實驗不是在說 JavaScript 不適合 SEO。它真正說的是:如果你把頁面最重要的 SEO 資訊都延後到 client-side render 之後才出現,那你就是把索引速度、搜尋引擎一致性和可預測性一起拿去冒險。

如果你只想記一條規則,那就記這條:互動效果可以交給 JavaScript,但 SEO 的核心語意,盡量從第一個 HTML 回應就先交出去。這通常是最穩的。

相關文章