预渲染能与服务端渲染一样提高 SEO 优化,但前者比后者需要更少的配置,实现成本低。弱网环境下,预渲染能更快地呈现页面内容,减少页面可见时间。本篇文章主要介绍了本人实现预渲染的一个过程。
从
meta
标签中读取keywords
、description
的内容。根据语义化的
html
的标签爬取和分析内容。一个整体都是用div
标签的网站和正确使用了html5
标签的效果是不一样的。读取
a
标签里的链接,通过a
标签的链接可以跳转到别的网站。(爬虫是先跳转,还是继续爬内容再跳转,就看算法是广度优先还是深度优先了)像
h1 - h6
标签是具有不同程度的强调意义的。 一般将h1
视为重要内容。同样有强调内容还有strong
、em
标签。技术栈
vue v2.0
+vue-router
+webpack
+prerender-spa-plugin
+vue-meta-info
+vue-cli v2
具体步骤
-使用
npm
或yarn
安装prerender-spa-plugin
和vue-meta-info
的过程就不描述了。-在webpack中配置
prerender-spa-plugin
-配置先弄懂要配置在哪个文件里,配置是否生效。
vue-cli2
的配置文件很多,对这些文件不了解的话,很容易配置错地方。-这个配置只需要在
build
的时候可以生成预渲染好的html,所以应该配置在build/webpack.prod.conf.js
这个文件里。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56//在build/webpack.prod.conf.js添加引入
const PrerenderSpaPlugin = require('prerender-spa-plugin')//解决seo
const Renderer = PrerenderSpaPlugin.PuppeteerRenderer//解决seo
const webpackConfig = merge(baseWebpackConfig, {
plugins: [
// vue-cli生成的配置中就已有这个了,不要动
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
}),
// 在vue-cli生成的文件的基础上,只有下面这个才是我们要配置的
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
// 下面这句话非常重要!!!
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname, '../dist'),
// 对应自己的路由文件,比如index有参数,就需要写成 /index/param1。
routes: ['/', '/index', '/about', '/alPay', '/wxPay'],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event'
})
})
]
})
//然后在main.js中添加引入
import MetaInfo from 'vue-meta-info'
Vue.use(MetaInfo)
new Vue({
el: '#app',
router,
store,
render: h => h(App),
/* 这句非常重要,否则预渲染将不会启动 */
mounted () {
document.dispatchEvent(new Event('render-event'))
}
})然后运行一下
npm run build
。看一下生成的dist
的目录里是不是有每个路由名称对应的文件夹。然后找个 目录里 的index.html
用IDE打开,看文件内容里是否有该文件应该有的内容。有的话,这步就成功了在vue中使用
vue-meta-info
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<template>
<div>
首页
</div>
</template>
export default {
metaInfo: {
title: '我是一个title',
meta: [
{
name: 'keywords',
content: '关键字1,关键字2,关键字3'
},
{
name: 'description',
content: '这是一段网页的描述'
}
]
}
}下面是特别需要注意的事项(否则将会出现问题)
这里使用的
prerender-spa-plugin
的版本是3.2.1
,在2.x
的版本中有个写法如下1
2
3
4
5
6
7
8
9
10
11
12
13var PrerenderSpaPlugin = require('prerender-spa-plugin')
const webpackConfig = merge(baseWebpackConfig, {
plugins: {
//配置 prerender-spa-plugin
new PrerenderSpaPlugin(
// 生成文件的路径,此处与webpack打包地址一致
path.join(config.build.assetsRoot), //config.build.assetsRoot为vue cli生成的配置,打包后的文件地址
// 配置要做预渲染的路由,只支持h5 history方式
[ '/', '/test']
)
}
})以上
2.x
的写法,在3.x
的版本会提示一个警告,让你采用对象的形式route 的
history
模式就是如下代码中配置预渲染方式下的 route 采用
history
模式,经过试验 得采用history模式,否则每个index.html文件的内容都会是一样的。1
2
3
4
5
6export default new Router({
mode: 'history',
routes: [
// ...
]
})注意事项1:
history
模式下的route,将不会以hash
的形式展示,也就是说,URL里没有#
了。注意事项2:但是需要注意
history
这种模式会出现页面刷新后出现404页面问题。vue.js官方教程里提到的解决办法可以参考