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'
现在就这样了!享受预告片吧!