Server-side rendering (SSR) involves rendering the same component as server-side HTML strings, sending them directly to the browser, and finally “activating” these static tags into a fully interactive application on the client side.

Unlike pure client-side single-page applications (SPA), server-side rendering can solve the problem of slow first-screen rendering and SEO search.

Vue SSR can be implemented using nuxt. js, as well as vuE-SSR.

Vue-ssr implementation principle

How it works: The Source part is the Source code we wrote, and all the code has a common entry, app.js, followed by the server entry

(entry-server.js) and client-side entry (entry-client.js). After compiling all the source code, we packaged two bundles, namely Server bundle and Client Bundle, through the construction of Webpack. When the user visits the page, first through the server entrance, vUE is assembled into HTML string, and mixed into the HTML template accessed by the client, and finally the whole SSR rendering process is completed.

Simple implementation

The installation

npm install vue vue-server-renderer --save
Copy the code

The directory structure

SRC ├ ─ ─ components │ ├ ─ ─ Foo vue │ ├ ─ ─ Bar. The vue │ └ ─ ─ Baz. Vue ├ ─ ─ App. Vue ├ ─ ─ App. Js # general entry (universal entry) ├ ─ ─ Entry-client. js # only run in browser ├ ─ entry-server.js # only run on serverCopy the code

App.js is a generic entry point for the application, and the entry should create a new Vue instance for each request. Because Node.js is a long-running process, it can easily lead to cross-request state pollution if we use a shared instance between multiple requests.

Therefore, instead of creating an application instance directly, we should expose a factory function that can be executed repeatedly to create a new application instance for each request, similar to how each user uses a new application instance in his or her browser.

Export function createApp () {const app = new Vue({// Root instance simple render application component. render: h => h(App) }) return { app } }Copy the code

Entry -client.js Client entry simply creates the application and mounts it into the DOM

$mount('#app') import {createApp} from './app' const {app} = createApp()Copy the code

Entry-server.js Server Entry uses the default export function to export and calls this function repeatedly on each render

import { createApp } from './app'

export default context => {
  const { app } = createApp()
  return app
}
Copy the code

Vue-router is used to implement routing

Similar to creating a Vue instance, return a function

// router.js import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export function createRouter () { Return new Router({mode: 'history', // routes: [//... })}Copy the code

Add vue-router to app.js

Export function createApp () {// createRouter instance const router = createRouter() const app = new Vue({// inject router into root Vue Router, render: h => h(App)}) render: h => h(App)}Copy the code

Implement server-side routing logic in entry-server.js

Export default Async Context => {// Since it may be an asynchronous route hook function or component, we will return a Promise so that the server can wait for everything to be ready before rendering. const { app, Router} = createApp() router.push(context.url) router.push(context.url) // Wait until the router has finished parsing possible asynchronous components and hook functions to await new Promise(router.onReady.bind(router)) return app }Copy the code