SEO 在 SPA 站點中的實踐

背景

image

觀察基于 create-react-doc 搭建的文檔站點, 發(fā)現(xiàn)網(wǎng)頁代碼光禿禿的一片(見下圖)。這顯然是單頁應用 (SPA) 站點的通病 —— 不利于文檔被搜索引擎搜索 (SEO)。

image

難道 SPA 站點就無法進行 SEO 了么, 那么 Gatsby、nuxt 等框架又為何能作為不少博主搭建博客的首選方案呢, 此類框架賦能 SEO 的技術原理是什么呢? 在好奇心的驅動下, 筆者嘗試對 creat-react-doc 進行賦能 SEO 之旅。

搜索引擎優(yōu)化

在實踐之前, 先從理論上分析為何單頁應用不能被搜索引擎搜索到。核心在于 爬蟲蜘蛛在執(zhí)行爬取的過程中, 不會去執(zhí)行網(wǎng)頁中的 JS 邏輯, 所以隱藏在 JS 中的跳轉邏輯也不會被執(zhí)行。

查看當前 SPA 站點打包后的代碼, 除了一個根目錄 index.html 外, 其它都是注入的 JS 邏輯, 因此瀏覽器自然不會對其進行 SEO。

image

此外, 搜索引擎詳優(yōu)化是一門較復雜的學問。如果你對 SEO 優(yōu)化比較陌生, 建議閱讀搜索引擎優(yōu)化 (SEO) 新手指南 一文, Google 搜索中心給出了全面的 17 個最佳做法, 以及 33 個應避免的做法, 這也是筆者近期在實踐的部分。

SEO 在 SPA 站點中的實踐案例

在輕文檔站點的背景前提下, 我們暫不考慮 SSR 方案。

對市面上文檔站點的 SEO 方案調研后, 筆者總結為如下四類:

  • 靜態(tài)模板渲染方案
  • 404 重定向方案
  • SSG 方案
  • 預渲染方案

靜態(tài)模板渲染方案

靜態(tài)模板渲染方案以 hexo 最為典型, 此類框架需要指定特定的模板語言(比如 pug)來開發(fā)主題, 從而達到網(wǎng)頁內容直出的目的。

404 重定向方案

404 重定向方案的原理主要是利用 GitHub Pages 的 404 機制進行重定向。比較典型的案例有 spa-github-pages、sghpa。

但是遺憾的是 2019 年 Google 調整了爬蟲算法, 因此此類重定向方案在當下是無利于 SEO 的。spa-github-pages 作者也表示如果需要 SEO 的話, 使用 SSG 方案或者付費方案 Netlify。

image

SSG 方案

SSG 方案全稱為 static site generator, 中文可譯為路由靜態(tài)化方案。社區(qū)上 nuxt、Gatsby 等框架賦能 SEO 的技術無一例外可以歸類此類 SSG 方案。

以 nuxt 框架為例, 在約定式路由的基礎上, 其通過執(zhí)行 nuxt generate 命令將 vue 文件轉化為靜態(tài)網(wǎng)頁。

例子:

-| pages/
---| about.vue/
---| index.vue/

靜態(tài)化后變成:

-| dist/
---| about/
-----| index.html
---| index.html

經(jīng)過路由靜態(tài)化后, 此時的文檔目錄結構可以托管于任何一個靜態(tài)站點服務商。

預渲染方案

經(jīng)過上文對 SSG 方案的分析, 此時 SPA 站點的優(yōu)化關鍵已經(jīng)躍然紙上 —— 靜態(tài)化路由。相較于 nuxt、Gatsby 等框架存在約定式路由的限制, create-react-doc 在目錄結構上的組織靈活自由。它的建站理念是文件即站點, 同時它對存量 markdown 文檔的遷移也十分便捷。

blog 項目結構為例, 其文檔結構如下:

-| BasicSkill/
---| basic/
-----| DOM.md
-----| HTML5.md

靜態(tài)化后應該變成:

-| BasicSkill/
---| basic/
-----| DOM
-------| index.html
-----| HTML5
-------| index.html

經(jīng)過調研, 該構思與 prerender-spa-plugin 預渲染方案一拍即合。預渲染方案的原理可以見如下圖:

image

至此技術選型定下為使用預渲染方案實現(xiàn) SSG。

預渲染方案實踐

create-react-doc 在預渲染方案實踐的步驟簡單概況如下(完整改動可見 mr):

  • 改造 hash 路由為 history 路由。因為 history 路由結構與文檔靜態(tài)化目錄結構天然匹配。
export default function RouterRoot() {
  return (
-    <HashRouter>
+    <BrowserRouter>
      <RoutersContainer />
-    </HashRouter>
+    </BrowserRouter>
  )
}
  • 在開發(fā)環(huán)境、生成環(huán)境的基礎上新增預渲染環(huán)境, 同時對路由進行環(huán)境匹配。其主要解決了資源文件主域名下的子路徑的對應關系。過程比較曲折, 感興趣的同學可以見 issue。
const ifProd = env === 'prod'
+ const ifPrerender = window.__PRERENDER_INJECTED && window.__PRERENDER_INJECTED.prerender
+ const ifAddPrefix = ifProd && !ifPrerender

<Route
  key={item.path}
  exact
-  path={item.path}
+  path={ifAddPrefix ? `/${repo}${item.path}` : item.path}
  render={() => { ... }}
/>
  • 兼容 prerender-spa-plugin 在 webpack 5 的使用。

官方版本當前未支持 webpack 5, 詳見 issue, 同時筆者存在對預渲染后執(zhí)行回調的需求。因此當前 fork 了一份版本 出來, 解決了以上問題。

經(jīng)過上述步驟的實踐, 終于在 SPA 站點中實現(xiàn)了靜態(tài)化路由。

image

SEO 優(yōu)化附加 buff, 站點秒開?

SEO 優(yōu)化至此, 來看下站點優(yōu)化前后 FP、FCP、LCP 等指標數(shù)據(jù)的變化。

blog 站點為例, 優(yōu)化前后的指標數(shù)據(jù)如下(數(shù)據(jù)指標統(tǒng)計來自未使用梯子訪問 gh-pages):

優(yōu)化前: 接入預渲染方案前, 首次繪制(FP、FCP) 的時間節(jié)點在 8s 左右, LCP 在 17s 左右。

image

優(yōu)化后: 接入預渲染方案后, 首次繪制時間節(jié)點在 1s 之內開始, LCP 在 1.5s 之內。

image

對比優(yōu)化前后: 首屏繪制速度提升了 8 倍, 最大內容繪制速度提升 11 倍。本想優(yōu)化 SEO, 結果站點性能優(yōu)化的方式又 get 了一個。

生成站點地圖 Sitemap

在完成預渲染實現(xiàn)站點路由靜態(tài)化后, 距離 SEO 的目標又近了一步。暫且拋開 SEO 優(yōu)化細節(jié), 單刀直入 SEO 核心腹地 站點地圖

站點地圖 Sitemap 格式與各字段含義簡單說明如下:

<?xml version="1.0" encoding="utf-8"?>
<urlset>
  <!-- 必填標簽, 這是具體某一個鏈接的定義入口,每一條數(shù)據(jù)都要用 <url> 和 </url> 包含在里面, 這是必須的 -->
  <url>
    <!-- 必填, URL 鏈接地址,長度不得超過 256 字節(jié) -->
    <loc>http://www.yoursite.com/yoursite.html</loc>
    <!-- 可以不提交該標簽, 用來指定該鏈接的最后更新時間 -->
    <lastmod>2021-03-06</lastmod>
    <!-- 可以不提交該標簽, 用這個標簽告訴此鏈接可能會出現(xiàn)的更新頻率 -->
    <changefreq>daily</changefreq>
    <!-- 可以不提交該標簽, 用來指定此鏈接相對于其他鏈接的優(yōu)先權比值,此值定于 0.0-1.0 之間 -->
    <priority>0.8</priority>
  </url>
</urlset>

上述 sitemap 中, lastmod、changefreq、priority 字段對 SEO 沒那么重要, 可以見 how-to-create-a-sitemap

根據(jù)上述結構, 筆者開發(fā)了 create-react-doc 的站點地圖生成包 crd-generator-sitemap, 其邏輯就是將預渲染的路由路徑拼接成上述格式。

使用方只需在站點根目錄的 config.yml 添加如下參數(shù)便可以在自動化發(fā)版過程中自動生成 sitemap

seo:
  google: true

將生成的站點地圖往 Google Search Console 中提交試試吧,

image

最后驗證下 Google 搜索站點優(yōu)化前后效果。

優(yōu)化前: 只搜索到一條數(shù)據(jù)。

image

優(yōu)化后: 搜索到站點地圖中聲明的位置數(shù)據(jù)。

image

至此使用 SSG 優(yōu)化 SPA 站點實現(xiàn) SEO 的完整流程完整實現(xiàn)了一遍。后續(xù)便剩下參照 搜索引擎優(yōu)化 (SEO) 新手指南 做一些 SEO 細節(jié)方面的優(yōu)化以及支持更多搜索引擎了。

小結

本文從 SPA 站點實現(xiàn) SEO 作為切入點, 先后介紹了 SEO 的基本原理, SEO 在 SPA 站點中的 4 種實踐案例, 并結合 create-react-doc SPA 框架進行完整的 SEO 實踐。

如果本文對您有所幫助, 歡迎 star、反饋

相關鏈接

原文出處

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容