VUE预渲染 webpack prerender-spa-plugin

预渲染就是在构建阶段(npm run build)生成特定路由的html静态页面,利用webpack的prerender-spa-plugin 插件。
参考:https://www.npmjs.com/package/prerender-spa-plugin

  1. 安装 prerender-spa-plugin
    npm install prerender-spa-plugin --save-dev
  2. 配置 vue.config.js
    headless设置为false的话,构建的时候会弹出浏览器窗口,仅在调试时使用,在生成环境中不需要设置为false。
    server中指定的port是预渲染时的端口。
    预渲染的时候,首先webpack会启动一个本地环境,然后prerender-spa-plugin插件会依赖puppeteer,也就是谷歌的无头浏览器插件。
    依次爬取routes中设置的页面,将爬取获取的内容生成指定的html。
    在这里插入图片描述
  3. 使用vue-meta-info组件设置meta和title。
    注意静态和动态路由设置的方式略有差别。
    参考:https://www.npmjs.com/package/vue-meta-info

那么经过上面这3步之后,在本地构建时预渲染的页面就可以正常生成。

接下来就是服务器部署。
在linux上支持prerender-spa-plugin 预渲染,是需要额外手动配置的。

  1. linux服务器编译报错
    参考官方解决方案,安装依赖包。Centos和其他的还不一样,docker环境也不一样。
    https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix
yum install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc
  1. nginx配置,加了一个 $uri/,否则预编译不生效。
    在这里插入图片描述

到这为止,预渲染就基本完成了!

但是仔细观察,还存在一些问题。

  • 问题1 查看源代码,发现meta的keywords和description有2个,title有一个为正常。如果页面中存在2个meta信息,第一个有效,第二个是无效的。在这里插入图片描述
    分析原因: 因为index.html中已经设置了meta的keywords和description,在vue组件中设置的meta的keywords和description,只会追加,并不会替代。所有就变成2个。
    但是如果删除掉index.html中设置的meta,就会出现预渲染以外的页面,没有title和meta信息,也不合理。
    解决方案: 增加一个模板入口文件index2.html,那么会有两个模板文件index.html和index2.html,预编译indexPath指定使用index2.html,在index2.html中不设置meta和title。正常渲染使用index.html,在index.html中正常设置meta和title。
    这样预渲染的页面就会有1个meta,预渲染以外的页面也可以正常有meta。
    同样这个也需要nginx设置,如上图。主页面请求index2.html,其他页面请求index.html.
  • 问题2 页面存在闪屏现象,就是在页面请求ajax返回数据页面渲染之前会先加载预渲染的页面,特别是数据变化大的页面,比如主页,过渡效果不自然。
    分析原因: 在ajax请求数据完成之前,页面显示的是预渲染页面,ajax请求完成后会替换掉 <div id="app"></div>中的内容,因此页面闪屏。
    解决方案: 增加loading效果,loading替换预渲染的内容显示。预渲染编译静态页面确实会提高加载速度,但是仅限于,比如公司介绍,都是静态内容的页面,如果动态内容很多,用户体验非常不好。
    注意一点就是预渲染页面的loading和预渲染以外的loading加的方式会不同。
    这个问题,每个人解决方式可能不同。
    我的实现方式判断当前port,当port是8001的时候,我会认为这是预渲染的请求,那么我会直接加一层Loading。那么实际上在显示的时候,就会加载loading然后显示ajax请求回来渲染的页面,这样不会有闪屏。
    预渲染以外的页面加loading,在index.html和index2.html中加入下面代码。
    在这里插入图片描述
    App.vue的钩子中,使其隐藏。
    在这里插入图片描述

这样会在刷新页面的时候,避免白屏时间长,影响用户体验,这样修改之后白屏的时候就会被Loading效果替代。300ms可以根据需求修改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章