spa单页应用seo优化方案——启动无头浏览器预渲染
- 需要在服务器安装chromium浏览器
yum -y install chromium
- 新建一个项目
npm init
初始化 - 在
package.json
里面加入下面的依赖说明,加入后执行npm install
"dependencies": {
"express": "^4.17.1",
"html-minifier": "^4.0.0"
},
"devDependencies": {
"puppeteer": "^10.0.0"
}
- 新建
puppeteer_pool.js
文件
const puppeteer = require('puppeteer')
const MAX_WSE = 2; //启动几个浏览器
let WSE_LIST = []; //存储browserWSEndpoint列表
//负载均衡
(async () => {
for (var i = 0; i < MAX_WSE; i++) {
const browser = await puppeteer.launch({
//无头模式
headless: true,
//参数
args: [
'--disable-gpu',
'--disable-dev-shm-usage',
'--disable-setuid-sandbox',
'--no-first-run',
'--no-sandbox',
'--no-zygote',
'--single-process'
]
});
browserWSEndpoint = await browser.wsEndpoint();
WSE_LIST.push(browserWSEndpoint);
}
})();
module.exports = WSE_LIST
- 新建
spider.js
文件
const puppeteer = require('puppeteer')
const WSE_LIST = require('./puppeteer_pool.js')
const spider = async (url) => {
let tmp = Math.floor(Math.random() * WSE_LIST.length);
//随机获取浏览器
let browserWSEndpoint = WSE_LIST[tmp];
//连接
const browser = await puppeteer.connect({
browserWSEndpoint
});
//打开一个标签页
var page = await browser.newPage();
//打开网页
await page.goto(url, {
timeout: 0, //连接超时时间,单位ms
waitUntil: 'networkidle0' //网络空闲说明已加载完毕
})
//获取渲染好的页面源码。不建议使用await page.content();获取页面,因为在我测试中发现,页面还没有完全加载。就获取到了。页面源码不完整。也就是动态路由没有加载。vue路由也配置了history模式
var html = await page.evaluate(() => {
return document.getElementsByTagName('html')[0].outerHTML;
});
await page.close();
return html;
}
module.exports = spider;
- 新建
server.js
文件
var express = require('express');
var app = express();
var spider = require("./spider.js")
var minify = require('html-minifier').minify;
app.get('*', async (req, res, next) => {
// 部署到服务器的完整URL
var url = req.protocol + '://'+ req.hostname + req.originalUrl;
console.log('请求的完整URL:' + url);
var content = await spider(url).catch((error) => {
console.log(error);
res.send('获取html内容失败');
return;
});
//由于是直接获取的源码,下面通过minify库压缩代码,也不知道是不是多余的。
content=minify(content,{removeComments: true,collapseWhitespace: true,minifyJS:true, minifyCSS:true});
res.send(content);
});
//监听3000端口
app.listen(3001, () => {
console.log('预渲染服务已启动!');
});
- 安装pm2
npm install pm2 -g
,开启预渲染服务pm2 start server.js
- 配置nginx,在合适的位置加入
if ($http_user_agent ~* "baiduspider|Googlebot|360Spider|Bingbot|Sogou Spider|Yahoo! Slurp China|Yahoo! Slurp|twitterbot|facebookexternalhit|rogerbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
proxy_pass http://127.0.0.1:3001;
}
- 测试服务,可以执行以下命令,会返回已经渲染并已执行过数据请求的
html
结构
curl -H 'User-agent:Googlebot' https://www.yourdomain.com
点击参考链接
感谢作者的分享
License:
CC BY 4.0