使用 prerender-spa-plugin v3 预渲染 Vue.js 应用程序

SSR(Server-Side Rendering)在这些日子里得到所有的爱。通过发送一个完整的HTML页面来加速初始页面的加载,而不是用几本脚本发送一个骨架,这是一个非常棒的想法。尽管有捕捉。SSR是 hard。有很多事情要担心,它很容易破坏。事实是,在大多数情况下,SSR是过度的。您可以在Vue.js应用程序中获得SSR的大部分好处,通过使用 prerender-spa-plugin在构建时将您的网站预先渲染到静态页面。

预渲染类似于与静态网站生成混合的服务器侧渲染,但更简单。你告诉预渲染器你想要的路径,然后它打开浏览器或类似的环境,加载页面,并将结果的HTML投放到匹配路径的文件路径中。这为您提供了完全渲染的静态页面,从而产生了更快的感知加载时间,无需奇怪的(http://www.backalleycoder.com/2016/05/13/sghpa-the-single-page-app-hack-for-github-pages/)。一旦JavaScript完成加载,您的应用程序将继续正常工作。

虽然预渲染不是一个银子子弹,但如果您有数百条路线,或需要预渲染动态内容而无需持有者,请不要使用它。

不管怎样,足够了chit-chat,让我们看看如何做到这一点。

<$>[警告] 注意: prerender-spa-plugin 3.0 仍处于 alpha 状态,因此 API 使用情况可能会在未来发生变化。

此指南假定您已与 webpack 简单模板设置了 vue-cli的快速项目,但对于任何 webpack 设置都相当相同。

使用

在您的 Vue.js 项目中安装 prerender-spa 插件。

1# Yarn
2$ yarn add prerender-spa-plugin@next -D
3# or NPM
4$ npm install prerender-spa-plugin@next --save-dev

然后,在webpack.config.js 中,要求()为相应的包。

 1[label webpack.config.js (Partial)]
 2var path = require('path')
 3var webpack = require('webpack')
 4// Add these
 5const PrerenderSPAPlugin = require('prerender-spa-plugin')
 6// Renders headlessly in a downloaded version of Chromium through puppeteer
 7const PuppeteerRenderer = PrerenderSPAPlugin.PuppeteerRenderer
 8
 9...
10
11module.exports = {
12  ...
13  plugins: [
14    new PrerenderSPAPlugin({
15      staticDir: __dirname, // The path to the folder where index.html is.
16      routes: ['/'], // List of routes to prerender.
17      renderer: new PuppeteerRenderer()
18    })
19  ]
20}
21
22...

现在,在重新运行 webpack 后,您应该发现项目根中的index.html现在也包含该页面的渲染内容。

交换回报器

PuppeteerRenderer很棒......除非它不是,它不是超快的,并且无法渲染大量页面,而不需要大量的系统资源。

如果你需要渲染数百或数千个页面,JSDOMRenderer可能是一个更好的选择。 jsdom欺骗了Node.js内部的浏览器环境,并尽可能地嘲笑它。

JSDOMRenderer 默认情况下没有prerender-spa-plugin

1# Yarn
2$ yarn add @prerenderer/renderer-jsdom -D
3# NPM
4$ npm install @prerenderer/renderer-jsdom --save-dev

JSDOMRenderer 示例:

 1var path = require('path')
 2var webpack = require('webpack')
 3// Add these
 4const PrerenderSPAPlugin = require('prerender-spa-plugin')
 5const JSDOMRenderer = require('@prerenderer/renderer-jsdom')
 6
 7...
 8
 9module.exports = {
10  ...
11  plugins: [
12    new PrerenderSPAPlugin({
13      staticDir: __dirname, // The path to the folder where index.html is.
14      routes: ['/'], // List of routes to prerender.
15      renderer: new JSDOMRenderer()
16    })
17  ]
18}
19
20...

如果你想要的话,你也可以实施自己的渲染器,这是相当微不足道的,请参阅官方文件以获取更多信息。

配置

延迟回报

你并不总是想把页面直接放下,有时你想等待一些事情发生。

所有三个渲染器都可以等待三个不同的触发器:

等待一个元素存在:

1renderer: new PuppeteerRenderer({
2  // Wait to render until the element specified is detected with document.querySelector.
3  renderAfterElementExists: '#app'
4})

** 等待文件事件的启动:**

您可以使用「document.dispatchEvent(新事件('my-document-event'))」激活应用程序中的事件。

1renderer: new PuppeteerRenderer({
2  // Wait to render until a specified event is fired on the document.
3  renderAfterDocumentEvent: 'my-document-event'
4})

** 等待指定时间:**

1renderer: new PuppeteerRenderer({
2  // Renders after 5000 milliseconds. (5 seconds.)
3  renderAfterTime: 5000
4})

变量注射

渲染器还可以在应用程序脚本运行之前将变量注入全球范围,如果您需要将某些东西传递给应用程序或改变行为,这取决于页面是否正在预先传输。

1renderer: new PuppeteerRenderer({
2  // injectProperty: '__PRERENDER_INJECTED'
3  // You can change the property added to window. The default is window.__PRERENDER_INJECTED.
4  // Inject can be any object that is JSON.stringify-able.
5  inject: {
6    nestLocation: 'bayou'
7  }
8})

现在在你的应用程序中, window.__PRERENDER_INJECTED.nestLocation === 'bayou'

现在就这样了!享受预告片吧!

Published At
Categories with 技术
Tagged with
comments powered by Disqus