预渲染
什么时候使用预渲染
- 只有少量页面需要SEO优化
- 仅仅提高首屏的渲染速度,且首屏的几乎只有静态数据的情况
可以在构建时(build),简单地生成针对特定路由的静态HTML文件,把前端页面作为一个静态的站点,然后渲染出来,而不是使用服务器去把对应的html渲染到前端,要保证做单页面,第一次请求就能请求到SEO的页面。
在webpack中可以用prerender-span-plugin这个插件来实现预渲染,先下载这个插件
npm -i prerender-spa-plugin
需要在vue.config.js中进行对该插件的配置(更多配置项可以到npm官网上查看这个插件的使用方法说明)
// 引入插件
const PrerenderSPAPlugin = require('prerender-spa-plugin');
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV !== 'production') return;
return {
plugins: [
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname,'dist'),
// 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
// 如果只是渲染首页,可以使用hash路由,但是如果要渲染其他页面,则一定要将路由改为history模式。
routes: ['/'],
// 这个很重要,如果没有配置这段,也不会进行预编译。
renderer: new Renderer({
inject: {
foo: 'bar'
},
// 是否开启无头浏览器,设置为false会在打包的时候看到浏览器弹出渲染路由。
headless: false,
// 注意要在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event'
})
})
],
};
}
}
在入口文件index.js上也要配置
new Vue({
router,
store,
render: h => h(App),
mounted () {
// 记得要与配置文件里的renderAfterDocumentEvent: 'render-event'对应上事件名。
document.dispatchEvent(new Event('render-event'))
}
}).$mount('#app')
服务端渲染
默认情况下,可以在浏览器中输出Vue组件,进行生成DOM和操作DOM,然而,也可以将同一个组件渲染为服务器端的HTML字符串,将它们直接发送到浏览器,最后将这些静态标记“激活”为客户端上完全可交互的应用程序。
如上图所示,vue组件在服务器端进行渲染,得到一个html,在这个html中已经包含了需要渲染出来的文字内容等等,那么在搜索引擎搜索拿html时,就可以查找到对应的文字,从而利于SEO
过程如上图所示,简单的实现和理解
简单实现代码
const express = require('express')()
const Vue = require('vue')
//创建服务端的渲染器
const renderer = require('vue-server-renderer').createRenderer()
//创建vue实例
const app = new Vue({
template: '<div>hello world</div>'
})
//服务端渲染的核心在于:
//通过vue-servver-render插件的renderToString()方法,将vue实例转换成字符串插入到html文档中
express.get('/', (req, res) => {
renderer.renderToString(app, (err, html) => {
if (err) {return res.state(500).end('运行错误')}
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
${html}
</body>
</html>
`)
})
})
express.listen(8881, ()=>{
console.log('服务器已开启!')
})