一、为什么vue项目对seo不友好
1、爬虫在爬取的过程中,不会去执行js,所以隐藏在js中的跳转也不会获取到。
2、vue通过js控制路由然后渲染出对应的页面,而搜索引擎蜘蛛是不会去执行页面的js的,导致搜索引擎蜘蛛只能收录index.html一个页面,在百度中就搜索不到相关的子页面的内容。
3、我们加载页面的时候,浏览器的渲染包含:html的解析、dom树的构建、cssom构建、javascript解析、布局、绘制,当解析到javascript的时候才回去触发vue的渲染,然后元素挂载到id为app的div上,这个时候我们才能看到我们页面的内容,所以即使vue渲染机制很快我们仍然能够看到一段时间的白屏情况,用户体验不好。
引起的问题
收录的页面少了->被抓取的页面就少了->点击量之类的也就少了;
不能对对应的页面做TDK(title, keywords, description)不同的配置,每个页面的title和meta标签都是一样的,不利于网络爬虫的爬取。
爬虫的内容
1、从 meta 标签中读取 keywords 、 description 的内容。
2、根据语义化的 html 的标签爬取和分析内容。一个整体都是用 div 标签的网站和正确使用了 html5 标签的效果是不一样的。
3、读取 a 标签里的链接,通过 a 标签的链接可以跳转到别的网站。(爬虫是先跳转,还是继续爬内容再跳转,就看算法是广度优先还是深度优先了)
4、像 h1 - h6 标签是具有不同程度的强调意义的。
一般将 h1 视为重要内容。同样有强调内容还有 strong 、 em 标签。
所以在查看页面的源代码时,需要能看到更多有利于爬虫的内容。如果没有做过优化只能看到根目录的html文件里面的内容,body里只有<div id="app"></div>,有利于爬虫的信息就只能看到头部配置的title、keywords和description,tdk对应的内容就很少。
二、如何优化
客户端渲染:用户访问 url,请求 html 文件,前端根据路由动态渲染页面内容。关键链路较长,有一定的白屏时间;
服务端渲染:用户访问 url,服务端根据访问路径请求所需数据,拼接成 html 字符串,返回给前端。前端接收到 html 时已有部分内容;
预渲染:构建阶段生成匹配预渲染路径的 html 文件(注意:每个需要预渲染的路由都有一个对应的 html)。构建出来的 html 文件已有部分内容。
由于不是新项目,服务端渲染的开发成本较高,业务场景也不需要对所有的页面做改善,所以选择了在构建时(build time)简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将你的前端作为一个完全静态的站点。
prerender-spa-plugin 是一个 webpack 插件用于在单页应用中预渲染静态 html 内容。因此,该插件限定了你的单页应用必须使用 webpack 构建,且它是框架无关的,无论你是使用 React 或 Vue 甚至不使用框架,都能用来进行预渲染。
页面加载过程:打包后的html中的静态内容其实只起到一个占位图的效果,之后解析到javascript的时候再触发vue的渲染,生成可交互的页面并覆盖之前的静态页面。这种实现可以解决首屏显示时间过长的问题。(确实首页白屏时间短了,但是我的网站的首页大部分内容是依赖接口返回的,预渲染的内容和我实际的内容可能会相差很大,造成页面有一个抖动跳转的表象,交互不是很好)
prerender-spa-plugin配置过程
安装:
npm install prerender-spa-plugin --save
代码配置
vue.config.js
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
configureWebpack: {
// provide the app's title in webpack's name field, so that
// it can be accessed in index.html to inject the correct title.
name: name,
plugins: [
//由于需要在测试环境进行测试,就没有针对环境去配置,实际需要只针对生产环境配置即可
new PrerenderSPAPlugin({
// 要求-给的WebPack-输出应用程序的路径预渲染。
staticDir: path.join(__dirname, './dist'),
// 必需,要渲染的路线。(这里一定要注意因为我的项目是前后端分离的项目,要配合nginx把对应路由对应到相应的文件的html文件上,不然预渲染的那些文件并不会加载到。)
routes: [ '/', '/login', '/register', '/home', '/productCenter'],
// 必须,要使用的实际渲染器,没有则不能预编译
renderer: new Renderer({
inject: {},
// 渲染时不显示浏览器窗口
headless: true,//这个地方有个大坑一定要注意,headless表示是否显示浏览器窗口,默认值为false ,但是代码在发到服务端的时候是跑在linux环境下的,是不可能打开浏览器窗口的,所以要显式的置为true
// 等待渲染,直到检测到指定元素。
// 例如,在项目入口使用`document.dispatchEvent(new Event('custom-render-trigger'))`
renderAfterDocumentEvent: 'render-event',
renderAfterTime: 5000
})
})
],
},
src/main.js
new Vue({
router,
store,
mounted() {
document.dispatchEvent(new Event('render-event'))
},
render: h => h(App)
}).$mount('#app')
router.js
export default new Router({ mode: 'history', routes})一定要设置为history模式
验证
运行npm run build,看一下生成的 dist 的目录里是不是有每个路由名称对应的文件夹。然后找个 目录里 的 index.html 用IDE打开,看文件内容里是否有该文件应该有的内容。有的话,就设置成功了。
http-server的安装和使用(可用可不用)
npm i -g http-server
运行:(cd到dist文件下) http-server
三、结合vue-meta-info不同的页面定义不同的TDK(title,description、keywords)
安装 vue-meta-info
npm i vue-meta-info --save
使用
在 main.js 文件中全局引入 vue-meta-info
import MetaInfo from 'vue-meta-info';
Vue.use(MetaInfo);
组件内静态使用 metaInfo
metaInfo: {
title:'My Example App',// set a title
meta: [{name:'keyWords',content:'My Example App'}]
link: [{rel:'asstes',href:'https://assets-cdn.github.com/'}]
}
注意:使用vue-meta-info之后,vue项目本身默认的要删掉,如果不删除会出现重复而不是覆盖
四、遇到的问题
1、项目使用jekins打包发布时,报错一、[Prerenderer - PuppeteerRenderer] Unable to start Puppeteer
把 headless配置为true
2、项目使用jekins打包发布时,报错二、/alidata1/jenkins/workspace/hengqin-life-face-new-uat2/node_modules/puppeteer/.local-chromium/linux-686378/chrome-linux/chrome: error while loading shared libraries:libXss.so.1: cannot open shared object file: No such file or directory
首先查看centos 版本
[root@localhost ~]#cat/etc/redhat-release
CentOS release 6.4(Final)
按照对应的版本下载包安装在服务器端
下载地址:https://pkgs.org/download/libXss.so.1
3、nginx配置了禁止百度 谷歌等等来爬取我们的网站,需要去掉
if ($http_user_agent ~* “qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot”) {
return 403;
}
五、收录不到的问题
1、做好了配置以后发现百度收录不到
sitemap提交:(您可以定期将网站链接放到Sitemap中,然后将Sitemap提交给百度。百度会周期性的抓取检查您提交的Sitemap,对其中的链接进行处理,但收录速度慢于API推送。)
生成对应的robots.txt(仅当您的网站包含不希望被搜索引擎收录的内容时,才需要使用robots.txt文件。如果您希望搜索引擎收录网站上所有内容,请勿建立robots.txt文件。)和sitemap.xml放在根目录下,并且在百度平台上主动提交收录(百度现在不支持xml嵌套。像正规网站,内容也不是很多的,不受影响。按普通sitemap提交就可以了)
自动推送:
2020-9-17百度搜索资源平台发布通知称,即日起搜索资源平台恢复“普通收录-自动推送”功能,自动推送仅对已关联主体的站点开放。
轻量级链接提交组件,将自动推送的JS代码放置在站点每一个页面源代码中,当页面被访问时,页面链接会自动推送给百度,有利于新页面更快被百度发现。
动推送由于实现便捷和后续维护成本低的特点,适合技术能力相对薄弱,无能力支持全天候实时主动推送程
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https'){
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else{
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
API推送:最为快速的提交方式,建议您将站点当天新产出链接立即通过此方式推送给百度,以保证新链接可以及时被百度收录。需要后端配合
手动提交:如果您不想通过程序提交,那么可以采用此种方式,手动将链接提交给百度。
2、具体seo收录的情况可直接在站长之家查看
六、痛苦的嘶吼
1、预渲染内容和真正渲染内容显示的跳动,这个没办法忍
2、到目前为止我的网站还是没有被百度收录到(一脸懵逼),但在别的平台收录的效果稍微好了点
3、我的系统已经做了很多功能,做服务端渲染基本上不可能。但我觉得要解决seo的问题,只有做服务端渲染效果才是最好的,天要亡我
七、参考文章
https://blog.csdn.net/weixin_44524835/article/details/110221911
避坑指南:https://zhuanlan.zhihu.com/p/272037693
网友评论