- 本篇文章使用场景:对于已经成型的 React SPA,使用 webpack打包 项目的 SEO 优化
1. 服务端渲染&预渲染
现在对于单页面应用的 SEO 优化分为两种,服务端渲染和预渲染。
- 服务端渲染
-
将完整的 html 输出到客户端,又被认为是‘同构’或‘通用’
优点
:首次渲染快(无需等待所有js都完成下载);利于SEO,节能缺点
:开发受限,需要处于Node.js server运行环境;更多的服务器负载(占用更大的CPU资源)
- 预渲染
获得服务端渲染的优点
对特定路由生成静态HTML文件,前端作为一个完全静态的站点
无需使用web服务器实时动态编译HTML
改善少数页面的SEO,可采用预渲染
若网站有成百上千条路线,预编译会非常缓慢(此情况慎用
因为本篇文章的使用场景为已经成型的项目,所以采用对代码没有侵入性的预渲染方案。
2. 使用插件prerender-spa-plugin
进行预渲染
安装阿里的
cnpm
工具
- 由于 node安装插件是从国外服务器下载,受网络影响大,速度慢且容易出现异常。而且本次使用的插件,需要安装一个大小为 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
# 记得在安装完成后再次执行
cnpm install
- 这里简单提一下
install
的参数
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
# 包将出现在依赖项中。这是默认值,除非出现-D或-O
# 安装包信息将加到devDependencies(开发阶段的依赖),所以开发阶段一般使用它
-D, --save-dev: Package will appear in your devDependencies
# 包将出现在您的devDependencies中
-O, --save-optional: Package will appear in your optionalDependencies.
# 包将出现在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
节点添加以下内容:
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:渲染时显示浏览器窗口。对调试很有用。
headless: false
})
})
]
- 最后按照正常流程执行打包
npm run build
就可以在 dist文件夹下面看见打包好的各个路由的预渲染界面
3. prerender-spa-plugin
插件原理
在这里稍微提一下插件的原理吧,其实也很容易想到,百度的搜索引擎是不会像谷歌一样,爬虫在访问网站的时候会执行一下脚本,完成单页面的渲染,之后完成网站的收录。百度是不会去执行的,所以百度爬虫得到的内容就是项目里面那个空的 html 文件,所以才不会收录。
那么prerender-spa-plugin
的插件呢,就会比较简单粗暴了,会在打包的时候就使用一个无头的浏览器,根据你的配置,去挨个访问你的文件,然后抓取渲染完成之后静态页面内容替换打包后的文件。这种方法对于代码没有侵入性。只是一种打包方法而已。