React SEO 策略和最佳實踐

已發表: 2022-03-11

開發 React 是為了創建聲明性模塊化跨平台的交互式 UI。 今天,它是用於編寫高性能前端應用程序的更流行(如果不是最流行)的 JavaScript 框架之一。 React 最初開髮用於編寫單頁應用程序 (SPA),現在用於創建成熟的網站和移動應用程序。

如果您在傳統 Web 開發方面擁有豐富的經驗並遷移到 React,您會注意到越來越多的 HTML 和 CSS 代碼遷移到 JavaScript。 這是因為 React 不建議直接創建或更新 UI 元素,而是描述 UI 的“狀態”。 React 然後會更新 DOM 以最有效的方式匹配狀態。

因此,對 UI 或 DOM 的所有更改都必須通過 React 的引擎進行。 儘管對開發人員來說很方便,但這可能意味著用戶的加載時間更長,搜索引擎需要更多的工作來查找和索引內容。

在本文中,我們將解決在構建具有 SEO 性能的 React 應用程序和網站時面臨的挑戰,我們將概述用於克服這些挑戰的幾種策略。

Google 如何抓取和索引網頁

谷歌接收了超過 90% 的在線搜索。 讓我們仔細看看它的爬取和索引過程。

這張取自 Google 文檔的快照可以幫助我們。 請注意,這是一個簡化的框圖。 實際的 Googlebot 要復雜得多。

Googlebot 索引網站的圖表。

注意事項:

  1. Googlebot 會維護一個抓取隊列,其中包含它需要在未來抓取和編入索引的所有網址。
  2. 當爬蟲空閒時,它會拾取隊列中的下一個 URL,發出請求並獲取 HTML。
  3. 解析 HTML 後,Googlebot 確定是否需要獲取並執行 JavaScript 來呈現內容。 如果是,則將 URL 添加到呈現隊列中。
  4. 稍後,渲染器獲取並執行 JavaScript 以渲染頁面。 它將呈現的 HTML 發送回處理單元。
  5. 處理單元提取網頁上提到的所有 URLs <a> tags ,並將它們添加回抓取隊列。
  6. 內容被添加到 Google 的索引中。

請注意,解析 HTML 的處理階段和執行 JavaScript 的渲染器階段之間有明顯的區別。

之所以存在這種區別,是因為執行 JavaScript 的成本很高,因為 Googlebot 需要查看超過 130 萬億個網頁。 因此,當 Googlebot 抓取網頁時,它會立即解析 HTML,然後將 JavaScript排隊等待稍後運行。 谷歌的文檔提到頁面會在渲染隊列中停留幾秒鐘,儘管它可能會更長。

還值得一提的是抓取預算的概念。 Google 的抓取受限於 Googlebot 實例的帶寬、時間和可用性。 它分配特定的預算或資源來索引每個網站。 如果您正在構建一個包含數千個頁面的內容豐富的大型網站(例如,電子商務網站),並且這些頁面使用大量 JavaScript 來呈現內容,那麼 Google 可能能夠從您的網站中讀取更少的內容。

注意:您可以在此處閱讀 Google 管理抓取預算的指南。

為什麼為 SEO 優化 React 具有挑戰性

我們對 Googlebot、抓取和索引編制的簡要概述僅涉及表面。 然而,軟件工程師應該識別搜索引擎在嘗試爬取和索引 React 頁面時面臨的潛在問題。 現在我們可以仔細看看是什麼讓 React SEO 具有挑戰性,以及開發人員可以做些什麼來解決和克服其中的一些挑戰。

空的首過內容

我們知道 React 應用程序嚴重依賴 JavaScript,而且它們經常遇到搜索引擎的問題。 這是因為 React 默認使用應用程序外殼模型。 初始 HTML 不包含任何有意義的內容,用戶或機器人必須執行 JavaScript 才能看到頁面的實際內容。

這種方法意味著 Googlebot 在第一遍檢測到一個空白頁面。 只有在呈現頁面時,Google 才能看到內容。 在處理數千個頁面時,這將延遲內容的索引。

加載時間和用戶體驗

獲取、解析和執行 JavaScript 需要時間。 此外,JavaScript 可能需要進行網絡調用來獲取內容,並且用戶可能需要等待一段時間才能查看請求的信息。

谷歌已經列出了一組與用戶體驗相關的網絡生命力,用於其排名標準。 較長的加載時間可能會影響用戶體驗得分,從而促使 Google 將網站排名較低。

我們將在下一節中詳細審查網站性能。

頁面元數據

<meta>標籤很有幫助,因為它們允許 Google 和其他社交媒體網站顯示適當的標題、縮略圖和頁面描述。 但是這些網站依賴於獲取的網頁的<head>標籤來獲取這些信息。 這些網站不會為目標頁面執行 JavaScript。

React 在客戶端呈現所有內容,包括元標記。 由於整個網站/應用程序的應用程序外殼是相同的,因此可能很難為各個頁面調整元數據。

網站地圖

站點地圖是一個文件,您可以在其中提供有關您站點上的頁面、視頻和其他文件以及它們之間的關係的信息。 像 Google 這樣的搜索引擎會讀取此文件以更智能地抓取您的網站。

React 沒有內置的方式來生成站點地圖。 如果你使用 React Router 之類的東西來處理路由,你可以找到可以生成站點地圖的工具,儘管這可能需要一些努力。

其他 SEO 考慮因素

這些注意事項通常與建立良好的 SEO 實踐有關。

  1. 擁有一個最佳的 URL 結構,讓人類和搜索引擎對頁面上的期望有一個很好的了解。
  2. 優化 robots.txt 文件可以幫助搜索機器人了解如何抓取您網站上的頁面。
  3. 使用 CDN 提供所有靜態資產,如 CSS、JS、字體等,並使用響應式圖像來減少加載時間。

我們可以通過使用服務器端渲染 (SSR) 或預渲染來解決上面列出的許多問題。 我們將在下面回顧這些方法。

輸入同構反應

同構的字典定義是“形式上對應或相似”。

在 React 術語中,這意味著服務器具有與客戶端類似的形式。 換句話說,您可以在服務器和客戶端上重用相同的 React 組件。

這種同構方法使服務器能夠渲染 React 應用程序並將渲染的版本發送給我們的用戶和搜索引擎,以便他們可以在 JavaScript 在後台加載和執行時立即查看內容。

Next.js 或 Gatsby 等框架已經普及了這種方法。 我們應該注意到,同構組件看起來可能與傳統的 React 組件有很大不同。 例如,它們可以包含在服務器而不是客戶端上運行的代碼。 它們甚至可以包含 API 機密(儘管服務器代碼在發送到客戶端之前已被剝離)。

需要注意的一點是,這些框架抽象了很多複雜性,但也引入了一種固執己見的代碼編寫方式。 我們將在本文中進一步探討性能權衡。

我們還將進行矩陣分析,以了解渲染路徑與網站性能之間的關係。 但在此之前,讓我們了解一些衡量網站性能的基礎知識。

網站性能指標

讓我們來看看搜索引擎用來對網站進行排名的一些因素。

除了快速準確地回答用戶的查詢外,谷歌認為一個好的網站應該具備以下屬性:

  • 它應該快速加載。
  • 用戶應該能夠在沒有太多等待時間的情況下訪問內容。
  • 它應該儘早與用戶的操作交互。
  • 它不應獲取不必要的數據或執行昂貴的代碼以防止耗盡用戶的數據或電池。

這些特徵大致映射到以下指標:

  • TTFB : Time to First Byte – 點擊鏈接和第一個內容進入之間的時間。
  • LCP : Largest Contentful Paint – 請求的文章變得可見的時間。 Google 建議將此值保持在 2.5 秒以下。
  • TTI :交互時間——頁面變為交互的時間(用戶可以滾動、點擊等)。
  • Bundle size – 在頁面完全可見和交互之前下載和執行的代碼的總字節數。

我們將重新審視這些指標,以更好地了解各種渲染路徑如何影響它們中的每一個。

接下來,讓我們了解 React 開發人員可用的不同渲染路徑。

渲染路徑

我們可以在瀏覽器或服務器上渲染一個 React 應用程序並產生不同的輸出。

客戶端和服務器端渲染應用程序之間的兩個功能發生了顯著變化,即路由代碼拆分。 我們在下面仔細看看這些。

客戶端渲染 (CSR)

客戶端渲染是 React SPA 的默認渲染路徑。 服務器將提供一個不包含任何內容的shell 應用程序。 一旦瀏覽器下載、解析和執行包含的 JavaScript 源代碼,就會填充或呈現HTML 內容。

路由功能由客戶端應用程序通過管理瀏覽器歷史記錄來處理。 這意味著無論請求哪個路由,都會提供相同的 HTML 文件,並且客戶端會在呈現後更新其視圖狀態。

代碼拆分相對簡單。 您可以使用動態導入或 React.lazy 拆分代碼,以便僅根據路由或用戶操作加載所需的依賴項。

如果頁面需要從服務器獲取數據來呈現內容——例如,博客標題或產品描述——它只能在相關組件被安裝和呈現時這樣做。

當網站獲取其他數據時,用戶很可能會看到“加載數據”標誌或指示符。

使用引導數據 (CSRB) 進行客戶端渲染

考慮與 CSR 相同的場景,但不是在呈現 DOM 後獲取數據,假設服務器發送的相關數據在提供的 HTML 中引導。

我們可以包含一個看起來像這樣的節點:

 <script type="application/json"> {"title": "My blog title", "comments":["comment 1","comment 2"]} </script>

並在組件掛載時解析它:

 var data = JSON.parse(document.getElementById('data').innerHTML);

我們剛剛為自己節省了往返服務器的時間。 我們稍後會看到權衡。

服務器端渲染到靜態內容 (SSRS)

想像一下我們需要動態生成 HTML 的場景。

例如,如果我們正在構建一個在線計算器並且用戶發出排序/calculate/34+15的查詢(省略 URL 轉義)。 我們需要處理查詢、評估結果並使用生成的 HTML 進行響應。

我們生成的 HTML 在結構上非常簡單,一旦生成的 HTML 被提供,我們就不需要 React 來管理和操作 DOM。

所以我們只是提供 HTML 和 CSS 內容。 您可以使用renderToStaticMarkup方法來實現這一點。

路由將完全由服務器處理,因為它需要為每個結果重新計算 HTML,儘管 CDN 緩存可用於更快地提供響應。 CSS 文件也可以被瀏覽器緩存,以便更快地加載後續頁面。

帶補液的服務器端渲染 (SSRH)

想像一下與上述相同的場景,但這次我們需要在客戶端上有一個功能齊全的 React 應用程序。

我們將在服務器上執行第一次渲染並將 HTML 內容與 JavaScript 文件一起發回。 React 將重新水化服務器呈現的標記,並且從此時起應用程序將像 CSR 應用程序一樣運行。

React 提供了內置的方法來執行這些操作。

第一個請求由服務器處理,隨後的渲染由客戶端處理。 因此,此類應用程序被稱為通用 React 應用程序(在服務器和客戶端上都呈現)。 處理路由的代碼可能會在客戶端和服務器上拆分(或複制)。

代碼拆分也有點棘手,因為ReactDOMServer不支持 React。 懶惰,因此您可能必須使用可加載組件之類的東西。

還應該注意的是, ReactDOMServer只執行淺渲染。 換句話說,雖然你的組件的 render 方法會被調用,但是像componentDidMount這樣的生命週期方法不會被調用。 因此,您需要重構代碼以使用替代方法向組件提供數據。

這就是像 NextJS 這樣的框架出現的地方。 它們掩蓋了與 SSRH 中的路由和代碼拆分相關的複雜性,並提供了更流暢的開發人員體驗。

當涉及到頁面性能時,這種方法會產生好壞參半的結果,我們稍後會注意到。

預渲染到靜態內容 (PRS)

如果我們可以在用戶請求之前呈現網頁怎麼辦? 這可以在構建時完成,也可以在數據更改時動態完成。

然後,我們可以在 CDN 上緩存生成的 HTML 內容,並在用戶請求時更快地提供它。

這在我們渲染內容之前稱為預渲染,即用戶請求。 這種方法可用於博客和電子商務應用程序,因為它們的內容通常不依賴於用戶提供的數據。

使用補液 (PRH) 進行預渲染

當客戶端渲染它時,我們可能希望我們的預渲染 HTML 成為一個功能齊全的 React 應用程序。

在處理第一個請求後,應用程序將像標準的 React 應用程序一樣運行。 這種模式在路由和代碼拆分功能方麵類似於上面描述的 SSRH。

績效矩陣

你一直在等待的時刻終於到來了。 是時候攤牌了。 讓我們看看這些渲染路徑中的每一個如何影響 Web 性能指標並確定獲勝者。

在這個矩陣中,我們根據每個渲染路徑在性能指標中的表現給它分配一個分數。

分數範圍從 1 到 5:

  • 1 = 不滿意
  • 2 = 差
  • 3 = 中等
  • 4 = 好
  • 5 = 優秀
TTFB
第一個字節的時間
液晶面板
最大的內容塗料
TTI
互動時間
捆綁大小
全部的
企業社會責任5
HTML 可以緩存在 CDN 上
1
多次訪問服務器以獲取 HTML 和數據
2
數據獲取 + JS 執行延遲
2
需要在渲染之前加載所有 JS 依賴項
10
社會責任委員會4
HTML 可以緩存,因為它不依賴於請求數據
3
數據與應用程序一起加載
3
JS 必須在交互之前獲取、解析和執行
2
需要在渲染之前加載所有 JS 依賴項
12
SSRS 3
HTML 在每個請求上生成並且不緩存
5
沒有 JS 有效負載或異步操作
5
頁面在第一次繪製後立即交互
5
僅包含必要的靜態內容
18
SSRH 3
HTML 在每個請求上生成並且不緩存
4
首次渲染會更快,因為服務器渲染了第一遍
2
速度較慢,因為 JS 需要在第一次 HTML 解析 + 繪製後對 DOM 進行水合
1
渲染的 HTML + JS 依賴需要下載
10
個人退休計劃5
HTML 緩存在 CDN 上
5
沒有 JS 有效負載或異步操作
5
頁面在第一次繪製後立即交互
5
僅包含必要的靜態內容
20
公屋5
HTML 緩存在 CDN 上
4
首次渲染會更快,因為服務器渲染了第一遍
2
速度較慢,因為 JS 需要在第一次 HTML 解析 + 繪製後對 DOM 進行水合
1
渲染的 HTML + JS 依賴需要下載
12

關鍵要點

預渲染到靜態內容(PRS) 會導致網站性能最高,而帶水合的服務器端渲染 (SSRH) 或客戶端渲染 (CSR) 可能會導致效果不佳。

也可以對網站的不同部分採用多種方法。 例如,這些性能指標對於面向公眾的網頁可能至關重要,因此它們可以更有效地被索引,而一旦用戶登錄並查看私人帳戶數據,它們的重要性可能會降低。

每個渲染路徑都代表您要在何處以及如何處理數據的權衡。 重要的是,工程團隊能夠清楚地看到和討論這些權衡,並選擇能夠最大限度地提高用戶幸福感的架構。

進一步閱讀和考慮

雖然我試圖涵蓋當前流行的技術,但這並不是一個詳盡的分析。 我強烈建議閱讀這篇文章,其中來自 Google 的開發人員討論了其他高級技術,例如流式服務器渲染、三態渲染和動態渲染(為爬蟲和用戶提供不同的響應)。

在構建內容繁重的網站時,您需要考慮的其他一些因素包括需要為您的作者提供良好的內容管理系統 (CMS),以及輕鬆生成/修改社交媒體預覽和針對不同屏幕尺寸優化圖像的能力。