Open masterkong opened 4 years ago
如果你调研服务器端渲染 (SSR) 只是用来改善少数营销页面(例如 /, /about, /contact 等)的 SEO,那么你可能需要预渲染。无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时 (build time) 简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将你的前端作为一个完全静态的站点。
预渲染页面方式由于不需要web服务器的参与,设置比SSR更简单,特别适合用来展示一些静态页面,比如根据页面UI来自动生成骨架屏。
npm install prerender-spa-plugin --save-dev
prerender-spa-plugin本身的安装非常简单,但是它所依赖的 puppeteer 却有可能让你吃苦头。由于网络原因,直接从npm安装puppeteer有可能会失败,解决办法网络上有很多,最简单就是设置淘宝的镜像源npm config set registry https://registry.npm.taobao.org。
npm config set registry https://registry.npm.taobao.org
puppeteer的介绍可以参考之前的文章 Puppeteer入门简介
顺利安装完prerender-spa-plugin后,提前在环境中验证 puppeteer能让你少走点弯路。这点可能在自己开发用的电脑上不明显,但是在部署环境中就有可能踩坑。
本文用了一个简单的node脚本来验证puppeteer,如果成功生成了百度的截屏baidu.png,预渲染插件的使用就成功一大半了。
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']}); const page = await browser.newPage(); await page.goto('https://www.baidu.com'); await page.screenshot({path: 'baidu.png'}); await browser.close(); })();
在 CentOS 7.2 环境中验证就遇到了缺少了依赖库的错误。
/chrome-linux/chrome: error while loading shared libraries: libXss.so.1: cannot open shared object file: No such file or directory TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
按照 TROUBLESHOOTING 的提示 安装相应的依赖库
> 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 -y > yum update nss -y
如果在上述依赖库的安装过程还遇到类似以下报错
Error: Protected multilib versions: libXcursor-1.1.15-1.tl2.x86_64 != libXcursor-1.1.14-2.1.el7.i686 Error: Protected multilib versions: libXi-1.7.9-1.tl2.x86_64 != libXi-1.7.4-2.el7.i686 Error: Protected multilib versions: libXtst-1.2.3-1.tl2.x86_64 != libXtst-1.2.2-2.1.el7.i686
那么先可以删除报错的依赖库再安装
> yum remove libXcursor-1.1.14-2.1.el7.i686 libXi-1.7.4-2.el7.i686 libXtst-1.2.2-2.1.el7.i686 -y
prerender-spa-plugin的用法在官方文档有着很详细的说明,这里挑几个主要的配置项说下。(如果webpack中有用到 html-webpack-plugin 插件,一般是在此之后再配置 prerender-spa-plugin)
const path = require('path') const PrerenderSPAPlugin = require('prerender-spa-plugin') const Renderer = PrerenderSPAPlugin.PuppeteerRenderer module.exports = { plugins: [ ... new HtmlWebpackPlugin(), ... new PrerenderSPAPlugin({ // 必填 - webpack输出用于预渲染的html文件的路径. staticDir: path.join(__dirname, 'dist'), // 必填 - 需要预渲染的vue-router路由. routes: ['/', '/about'], // 可选 - 预渲染的html文件路径。默认为 path.join(staticDir, 'index.html') indexPath: path.join(__dirname, 'dist/index.html'), // 可选 - 对html文件内容以及生成的最终路径进行自定义处理 postProcess(renderedRoute) { // 删除html中的空白字符 renderedRoute.html = renderedRoute.html.split(/>[\s]+</gmi).join('><'); // 将生成的html重命名为prerender.html renderedRoute.outputPath = path.join(__dirname, 'dist', renderedRoute.route, 'prerender.html'); return renderedRoute }, // The actual renderer to use. renderer: new Renderer({ // puppeteer配置参数 args: ['--no-sandbox', '--disable-setuid-sandbox'], // 当设置为false时,可以看到渲染时调用的浏览器,在调试页面时非常有用 headless: true, // 可选 - 当 document 触发以下事件时才开始渲染页面,使用vue组件时建议配置 renderAfterDocumentEvent: 'render-event' }) }) ] }
配置了 renderAfterDocumentEvent: 'render-event'时,vue组件需要进行相应的修改
renderAfterDocumentEvent: 'render-event'
new Vue({ el: '#app', ... mounted() { // 通知 prerender-spa-plugin 可以渲染了 document.dispatchEvent(new Event('render-event')); } });
经过上面的步骤,prerender-spa-plugin插件的配置算是完成了,但并不代表就一切顺利,下面就记录几个遇到的问题。
这个问题是 Vue主组件模板也需要设置跟el配置项一样的 id。
el
id
// App.vue <template> <div id="app"> </div> </template>
这个问题一般是渲染的页面出错或者请求的 css/js 文件没有正常加载,导致没有触发renderAfterDocumentEvent配置的事件名。
renderAfterDocumentEvent
curl
你好 文章可以授权"深圳湾码农"公众号转载吗?会注明作者和原文链接
可以
Vue预渲染插件prerender-spa-plugin使用全记录
服务器端渲染 vs 预渲染 (SSR vs Prerendering)
预渲染页面方式由于不需要web服务器的参与,设置比SSR更简单,特别适合用来展示一些静态页面,比如根据页面UI来自动生成骨架屏。
安装
npm install prerender-spa-plugin --save-dev
prerender-spa-plugin本身的安装非常简单,但是它所依赖的 puppeteer 却有可能让你吃苦头。由于网络原因,直接从npm安装puppeteer有可能会失败,解决办法网络上有很多,最简单就是设置淘宝的镜像源
npm config set registry https://registry.npm.taobao.org
。puppeteer的介绍可以参考之前的文章 Puppeteer入门简介
验证puppeteer
顺利安装完prerender-spa-plugin后,提前在环境中验证 puppeteer能让你少走点弯路。这点可能在自己开发用的电脑上不明显,但是在部署环境中就有可能踩坑。
本文用了一个简单的node脚本来验证puppeteer,如果成功生成了百度的截屏baidu.png,预渲染插件的使用就成功一大半了。
在 CentOS 7.2 环境中验证就遇到了缺少了依赖库的错误。
按照 TROUBLESHOOTING 的提示 安装相应的依赖库
如果在上述依赖库的安装过程还遇到类似以下报错
那么先可以删除报错的依赖库再安装
预渲染配置
prerender-spa-plugin的用法在官方文档有着很详细的说明,这里挑几个主要的配置项说下。(如果webpack中有用到 html-webpack-plugin 插件,一般是在此之后再配置 prerender-spa-plugin)
配置了
renderAfterDocumentEvent: 'render-event'
时,vue组件需要进行相应的修改踩坑
经过上面的步骤,prerender-spa-plugin插件的配置算是完成了,但并不代表就一切顺利,下面就记录几个遇到的问题。
1、渲染的页面成功生成,但是页面运行后却是静态页面,相应的 js 不起作用
这个问题是 Vue主组件模板也需要设置跟
el
配置项一样的id
。2、编译过程中一直卡死
这个问题一般是渲染的页面出错或者请求的 css/js 文件没有正常加载,导致没有触发
renderAfterDocumentEvent
配置的事件名。curl
命令)。参考