Vue预渲染与服务端渲染

390 阅读2分钟

原文地址

Vue.js 服务器端渲染指南 | Vue SSR 指南 (vuejs.org)

后面的内容大部分都是copy原文了

服务端渲染(SSR)

什么是服务端渲染

将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。

服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器客户端上运行。

服务端渲染的利弊

  • 更好的 SEO
  • 更快的内容到达时间 (time-to-content)

  • 开发条件所限。
  • 涉及构建设置和部署的更多要求。
  • 更多的服务器端负载。

总结:是否真的需要它。这主要取决于内容到达时间 (time-to-content) 对应用程序的重要程度。

基本用法

server.js,用express搭建的服务,主要方法renderToString、createSSRApp,拼接字符串返回给浏览器进行渲染。html字符串还需加载vue进行同构。

import express from 'express';
import { renderToString } from 'vue/server-renderer';
import APP from './App.js';
import { createSSRApp } from 'vue';

const server = express();

server.get('/', (req, res) => {
  const app = createSSRApp(APP);

  renderToString(app).then((html) => {
    res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Vue SSR Example</title>
        <script type="importmap">
          {
            "imports": {
              "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
            }
          }
        </script>
        <script type="module" src="/client.js"></script>
      </head>
      <body>
        <div id="app">${html}</div>
      </body>
    </html>
    `);
  });
});

server.use(express.static('.'));

server.listen(3000, () => {
  console.log('ready');
});

App.js,模仿vue sfc生成的对象。

export default {
  data: () => ({ count: 1 }),
  template: `<div @click="count++">{{ count }}</div>`,
}

client.js,同项目中main.js

import { createSSRApp } from 'vue';
import APP from './App.js';
createSSRApp(APP).mount('#app');

接着跑node server.js。

行为展示

image.png

预渲染(Prerendering)

如果你调研服务器端渲染 (SSR) 只是用来改善少数营销页面(例如 //about/contact 等)的 SEO,那么你可能需要预渲染。无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时 (build time) 简单地生成针对特定路由的静态 HTML 文件。

预渲染的利弊

设置预渲染更简单,并可以将你的前端作为一个完全静态的站点。

预渲染不适用经常变化的数据,比如说股票代码网站,天气预报网站。 因为此时的数据是动态的,而预渲染时已经生成好了dom节点。 如果要兼容seo可以使用SSR。 预渲染不适用大量的路由页面,比如成千上百个路由,此时打包后预渲染将会非常慢。

基本用法

prerender-spa-plugin-next,GitHub - Tofandel/prerender-spa-plugin-next: Prerenders static HTML in a single-page application.

const path = require('path')
const { defineConfig } = require('@vue/cli-service')
const PrerenderSPAPlugin = require('prerender-spa-plugin-next')
module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    plugins: [
      new PrerenderSPAPlugin({
        // Required - Routes to render.
        routes: ['/', '/home'],
      })
    ]
  }
})

配置好打包后放到nginx或其他web server跑。

行为展示

访问路由 /

image.png

访问路由 /home

image.png

源码地址

预渲染:vueprerendering: vue 预渲染 官文实践 (gitee.com)

服务端渲染:VueSSRTest: VueSSR,官文实践 (gitee.com)

踩坑:Unable to prerender all routes!

解决:我的是Vue-cli@5,用的webpack5,改用prerender-spa-plugin-next,issue截图:

image.png