作者:Chancel, 更新:2019 Dec 05, 字数:5504, 已阅:803
博客网站以及一些扩展页面都是基于Vue全家桶开发的,后端直接使用Flask作为API提供数据,这段时间发现了低版本浏览器访问首页白屏以及百度收录的网站无法正确显示等问题
SEO全称搜索引擎优化(search engine optimization)
搜索引擎优化是一种透过了解搜索引擎的运作规则来调整网站,以及提高目的网站在有关搜索引擎内排名的方式。由于不少研究发现,搜索引擎的用户往往只会留意搜索结果最前面的几个条目,所以不少网站都希望透过各种形式来影响搜索引擎的排序,让自己的网站可以有优秀的搜索排名。当中尤以各种依靠广告维生的网站为甚。
从现实例子来看影响搜索引擎收录你网站的根据主要有如下几个因子
从上面我们可以看到影响SEO的因素非常多且很多不单纯是技术问题,这里不讨论非技术问题,可以参考上面的列表对非技术问题做相关处理,技术问题上主要是当前搜索引擎并不能很好地识别”SPA应用“
~~spa是放松保养疗法,中文也称水...这段划掉~~
SPA应用也称单页应用,single-page application(缩写SPA)
单页应用是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,而非传统的从服务器重新加载整个新页面。这种方法避免了页面之间切换打断用户体验,使应用程序更像一个桌面应用程序。在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面。尽管可以用位置散列或HTML5历史API来提供应用程序中单独逻辑页面的感知和导航能力,但页面在过程中的任何时间点都不会重新加载,也不会将控制转移到其他页面。与单页应用的交互通常涉及到与网页服务器后端的动态通信。
这是2003年就讨论过的概念,但国内直到2010年稍晚之后才逐渐兴起这个话题,目前支持单页应用的前端框架已经非常多了,主要有如下几个
他们所采用的通信技术基本都是Ajax/Websocket,通信所采用的数据格式通常是Json/XML,即服务端的MVC下放到了浏览器上执行,这样做会带来很多优点与弊端,着重说说弊端
解决SPA的SEO问题目前而言只有一个思路,那就是 判断爬虫行为并返回给渲染完成的网页,也就是当识别到爬虫行为的时候将SPA转换为传统方案 目前业界的解决方案也的确是沿着这种思路进行解决的,如果你采用的是VUE/AngularJS/React方案基本都是通用的 由于我的应用的后端Flask+前端Vue全家桶的,所以这里着重看看VUE的解决方案
后端直接渲染呈现给用户的最终HTML页面,关于SSR方案可以参考Vue.js 服务器端渲染指南
SSR方案可以有效减少网络请求速度,提升弱网环境下的体验(弱网环境下减少HTTP请求能减少大量等待时间)同时也兼顾了更好的SEO,但缺点一样很明显,需要引入NodeJS做服务端解析,引起更大的服务端负载,以及更高的维护成本,在并发量大的情况下也会面临普通应用所必须解决的诸多问题,私认为除非 为了解决低版本兼容与弱网环境问题否则单单为了SEO引入SSR并不值得
如果为了SEO引入SSR,那为什么还要做单页应用呢?VUE本身就是低侵入性的JavaScript框架,这不自相矛盾,该方案Pass
Nuxt.js是一个基于Vue.js的应用框架,对客户端/服务端基础架构进行抽象,Nuxt.js关注的是应用的UI渲染,其实就是VUESSR的集成方案,同样依赖于NodeJS
关于Nuxt.js方案可以参考关于 Nuxt.js
总体上来看Nexu.js方案性价比也是非常低,在后端已然做完的情况下是无法更换后端框架与语言的,更 适合于项目伊始就采用的技术框架,这样相对性价比就很高了,该方案一样也pass
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.
Puppteer是一个NodeJS的工具库,提供一系列基于Devtools协议的高级API来控制Chrome/Chromium,Puppteer默认没有界面运行,但她可以通过配置运行在完整(有界面)的Chrome/Chromium上
从SEO的原理考虑,其实就是因为部分搜索引擎不执行javascript从而导致页面是无意义的(一堆Meta标签),那么我们只需要返回有意义的HTML就行了,服务端渲染的思路显然除了SSR外,爬虫也可以解决这个问题,这个时候我们可以利用Puppeteer方案, Puppeteer比起其他方案的优点
这个展开尝试一下又是一篇文章,这里仅仅提供这个思路,具体的可以参考下下面这些资料
GoogleChrome/puppeteer - github.com Getting Started with Headless Chrome
如果你的SPA部分页面是数据变动不大,例如/about /contact等少数营销页面的SEO,那么预渲染就非常适合你的情况了
预渲染的工作原理是 在使用webpack打包VUE项目的时候简单地生成针对特定路由的静态HTML页面,也就是在生成的时候将页面数据拉一遍并保存好静态页面,自动添加到VUE项目内部结构去,这样每一次打包都会生成一份新的静态页面。
即:用户请求静态页面的时候会获取到一份事先准备好的静态页面,然后用户自己会再次获取到新的数据覆盖旧的数据
这个方案相对实时性来说可以接受,同时也兼顾了SEO优化,对于 博客类网站也还是比较合适的,但对某些实时性要求很高的网站可能就不太合适了(比赛直播之类的),并且方案本身不会破坏当前后端分离的体系
该方案的原理其实也是Puppeteer原理
个人博客类网站变动不大,也不存在太多复杂的路由,显然PrerenderSpaPlugin是最合适的方案,
npm install prerender-spa-plugin --save-dev
npm install puppeteer --save-dev
修改项目中关于 build/webpack.prod.conf.js文件,添加如下sample配置(复杂配置参考prerender-spa-plugin - github)
...
const PrerenderSpaPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSpaPlugin.PuppeteerRenderer;
...
const webpackConfig = merge(baseWebpackConfig, {
module: {
...
},
plugins: [
...
// PerenderSpaPlugin - 预渲染
new PrerenderSpaPlugin({
// 输出目录
staticDir: path.join(__dirname, "../dist"),
// 需要预渲染的路由
routes: [
"/",
"/books",
],
// 渲染配置
renderer: new Renderer({
inject: {},
// 等待页面加载10秒之后采集
renderAfterTime: 10000
})
})
]
验证是否渲染成功
项目地址/文档可以参考:prerender-spa-plugin - github.com
项目伊始可以考虑使用SSR方案,Nuxt.js是个不错考虑方案 如果不想替换已经写完的后端应用,显然引入预渲染是最好的方案,另外有兴趣也可以参考Allows your Javascript website to be crawled perfectly by search engines -PRERENDER
下次还是试试有意思的Puppeteer方案吧