常规情况下,我们加载页面的时候,浏览器渲染包含:html解析、dom树构建、cssom构建、js解析、布局、绘制。当解析到js的时候,才会去触发vue的渲染,然后元素挂载到id为app的div上,这个时候才能看见内容。虽然vue的渲染机制很快,但我们也有可能看见白屏状况。为了使用户在加载页面的时候不需要过长的等待,解决spa白屏情况,我们可以采用预渲染手段。
三种不同的渲染方式的区别:
(1)客户端渲染:用户访问url,请求html文件,前端根据路由动态渲染页面内容。有可能出现白屏,且SEO不友好。
(2)服务端渲染:用户访问url,服务端根据访问路径请求所需数据,拼接成html字符串,返回给前端,前端接收到html时已有当前url下的完整页面;
(3)预渲染:构建阶段生成匹配预渲染路径的html文件(注意:每个需要预渲染的路由都有一个对应的html—),构建出来的html文件已经有静态数据,需要ajax数据部分未构建。
预渲染解决的问题:
(1)SEO:单页应用的网站内容是根据当前路径动态渲染的,html文件中往往没有内容,网络爬虫不会等到页面脚本执行完再抓取
(2)弱网环境:当用户在一个弱网环境中访问站但的时候,我们需要京可能快的将内容呈现给他们。甚至是在js脚本被加载和解析之前
(3)低版本浏览器:用户的浏览器可能不支持我们的使用的js特性,预渲染或者服务端渲染能够让用户至少能看见首屏的内容,而不是一个空白的网页
1.安装
npm install prerender-spa-plugin --save
2.在vue.config.js里配置
// 实现预渲染
// const PrerenderSPAPlugin = require('prerender-spa-plugin')
const PrerenderSPAPlugin = require('@dreysolano/prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const path = require('path')
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
devServer: { // 设置代理
https: false,
},
configureWebpack: () => {
if (process.env.NODE_ENV === 'production') {
return {
plugins: [
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
routes: ['/'], // 需要预渲染的路由(视你的项目而定)
renderer: new Renderer({
inject: {
foo: 'bar'
},
renderAfterDocumentEvent: 'render-event'
})
})
]
}
}
}
})
3.在main.js中配置
new Vue({
router,
store,
render: h => h(App),
// 预渲染,这个注意加上,要不然不会执行预编译的
mounted() {
document.dispatchEvent(new Event('render-event'))
}
}).$mount('#app')
4.打包
npm run build
5.会在dist文件夹中生成对应的html页面
需要注意的一点,似乎路由需要用history模式