- 本篇文章使用場景:對于已經(jīng)成型的 React SPA,使用 webpack打包 項目的 SEO 優(yōu)化
1. 服務端渲染&預渲染
現(xiàn)在對于單頁面應用的 SEO 優(yōu)化分為兩種,服務端渲染和預渲染。
- 服務端渲染
-
將完整的 html 輸出到客戶端,又被認為是‘同構(gòu)’或‘通用’
優(yōu)點:首次渲染快(無需等待所有js都完成下載);利于SEO,節(jié)能缺點:開發(fā)受限,需要處于Node.js server運行環(huán)境;更多的服務器負載(占用更大的CPU資源)
- 預渲染
獲得服務端渲染的優(yōu)點
對特定路由生成靜態(tài)HTML文件,前端作為一個完全靜態(tài)的站點
無需使用web服務器實時動態(tài)編譯HTML
改善少數(shù)頁面的SEO,可采用預渲染
若網(wǎng)站有成百上千條路線,預編譯會非常緩慢(此情況慎用
因為本篇文章的使用場景為已經(jīng)成型的項目,所以采用對代碼沒有侵入性的預渲染方案。
2. 使用插件prerender-spa-plugin進行預渲染
安裝阿里的
cnpm工具
- 由于 node安裝插件是從國外服務器下載,受網(wǎng)絡影響大,速度慢且容易出現(xiàn)異常。而且本次使用的插件,需要安裝一個大小為 144M無界面的
Chrome瀏覽器。所以我們首先安裝cnpm工具。這里并不建議直接替換npm的倉庫地址改為淘寶鏡像的倉庫地址。因為這畢竟只是一個鏡像站點,萬一以后我們需要的的插件在鏡像站里面沒有就麻煩了。 - 使用阿里定制的 cnpm 命令行工具代替默認的 npm,輸入下面代碼進行安裝:
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
- 檢測
npm版本,以后安裝插件只需要輸入cnpm install即可
cnpm -v
安裝插件
# 會把X包安裝到node_modules目錄中 會在package.json的dependencies屬性下添加X
cnpm install prerender-spa-plugin --save
# 記得在安裝完成后再次執(zhí)行
cnpm install
- 這里簡單提一下
install的參數(shù)
npm install xxx
# 會把X包安裝到node_modules目錄中
# 不會修改package.json
# 之后運行npm install命令時,不會自動安裝X
-g
# 全局安裝
-S, --save
# 會把X包安裝到node_modules目錄中
# 會在package.json的dependencies屬性下添加X
# 之后運行npm install命令時,會自動安裝X到node_modules目錄中
-P, --save-prod: Package will appear in yourdependencies
# 包將出現(xiàn)在依賴項中。這是默認值,除非出現(xiàn)-D或-O
# 安裝包信息將加到devDependencies(開發(fā)階段的依賴),所以開發(fā)階段一般使用它
-D, --save-dev: Package will appear in your devDependencies
# 包將出現(xiàn)在您的devDependencies中
-O, --save-optional: Package will appear in your optionalDependencies.
# 包將出現(xiàn)在optionalDependencies中
–no-save: Prevents saving to dependencies
# 防止保存到依賴項
-E, –save-exact 精確安裝指定模塊版本
# 安裝包,默認會安裝最新的版本
npm install jquery --save-exact 或
npm install jquery -E
使用插件
-
webpack.prod.config.js文件中修改:
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
- 在文件中的
plugins節(jié)點添加以下內(nèi)容:
plugins: [
new PrerenderSPAPlugin({
//代碼打包目錄和以前配置的目錄保持一致
staticDir: path.join(__dirname, '../dist'),
indexPath: path.join(__dirname, '../dist', 'index.html'),
//routes:要預渲染的頁面訪問路由
routes: ['/', '/home', '/freeIp', '/buyMeal', '/getIp', '/getLongIp', '/recharge', '/help/check', '/company/check', '/login'],
renderer: new Renderer({
inject: {
foo: 'bar'
},
// headless:渲染時顯示瀏覽器窗口。對調(diào)試很有用。
headless: false
})
})
]
- 最后按照正常流程執(zhí)行打包
npm run build就可以在 dist文件夾下面看見打包好的各個路由的預渲染界面
3. prerender-spa-plugin插件原理
在這里稍微提一下插件的原理吧,其實也很容易想到,百度的搜索引擎是不會像谷歌一樣,爬蟲在訪問網(wǎng)站的時候會執(zhí)行一下腳本,完成單頁面的渲染,之后完成網(wǎng)站的收錄。百度是不會去執(zhí)行的,所以百度爬蟲得到的內(nèi)容就是項目里面那個空的 html 文件,所以才不會收錄。
那么prerender-spa-plugin的插件呢,就會比較簡單粗暴了,會在打包的時候就使用一個無頭的瀏覽器,根據(jù)你的配置,去挨個訪問你的文件,然后抓取渲染完成之后靜態(tài)頁面內(nèi)容替換打包后的文件。這種方法對于代碼沒有侵入性。只是一種打包方法而已。