background

On the service side rendering a lot of online, there are a lot of good article, why do I write a piece about the service side rendering, primarily to understand the problems that the small clip figure, if you don’t understand these small clip figure, may make some beginner students make of vertigo, I started when I was stuck in the small point, Understand these small points, may be just one of the small points, it is possible to let a lot of students on the server rendering soul enlightenment

Before we start, let’s make one thing clear: most of our front-end projects are single-page applications written through VUE or React. At this time, if you check the source code of the web page, you will find something like the following

From the above picture, can you get a sense of what this page is about? Anyway, I do not know, the network spider more do not know (loaded force point is not friendly to SEO), so, for some strong rely on search engines as a source of traffic network single page application, although in the experience of a lot better, but you will find that the search engine can not search your web page, surprised not surprise!

Therefore, how to retain the premise of single-page user experience, how to solve the problem of SEO, is the theme of this article: single-page application server rendering


Small point: As you can see, we are talking about server-side rendering for single-page applications, not simply server-side rendering

The target

Based on the above questions, let’s summarize the server rendering goals of the single page application:

  1. View the source code of any route page, which contains the content of the page
  2. In the process of user use, the attributes and experience of the single-page application are still retained

The first goal is achieved

Ok, let’s achieve the first goal above: view the source code of any route page, which contains the content of the page (this article takes vUE as an example)

To render a VUE application on the server, you need to have a Node server first. Let’s use Express to quickly implement the server

Tidbit: Some of you may wonder: why do you need a Node server for server rendering? Other servers, such as Tomcat, Apache, etc. Our purpose is to render the program written by Vue in the server into HTML and send it to the client, so, our server must be able to run vue, that is to say, our server must be able to execute JS, can execute JS, and as a server, is not immediately thought of node?

Step 1: Create a server

Let’s create a new server.js and write the following code

Execute and access, the server has

Step 2: Render the VUE component

Vue server renderer (renderer, vue server renderer, vUE server renderer

When you refresh the browser, you can still see Hello World, but this Hello World is not the same Hello World. At this point, the Hello World has already been rendered by the server and sent to the client

To better express what we mentioned in goal 1 (see the source code for any routing page, which contains the content of that page), we add routing functionality

Step 3: Introduce vue-Router to implement the routing function

First create router.js to import a route

According to the route, create three corresponding components, and write some corresponding content to each component

Details: Why is the routing mode history instead of hash, as discussed below

Create app. vue as the routing container

Once the routing file is ready, the next thing to do is to find the corresponding VUE component based on the requested address of the user, render it as HTML and return it to the client as originally done

First let’s create a new main.js, put the route into the vue instance, as follows, export a method to create vue instance

Create a new serverentry. js file as the server’s bundle entry file, where the context parameter is the context of the network request, which contains the address of the request. This context parameter is passed when server.js is called. By $router. The getMatchedComponents access to match the components, as follows:

Use the above file as an entry point and package it into bundle.server.js via Webpack

Note: Since we need to find the component to render using the requested URL, we use the history mode, since the hash mode is not sent to the server

Modify server.js as follows

Restart the service, this time to achieve our first goal: regardless of access/helloWord. /hellovue/helloReact /hellovue/helloReact /hellovue/helloReact

At this point, the first goal has been achieved, we implement the service side rendering, however, at this time by clicking on the link, and will send the request again, refresh the entire page, this is not we want, so let’s begin to implement the second goal: to remain single page properties and application experience, is a single application server page rendering

Second goal achieved

In order to retain the attributes and experience of a single page application, we just need to let Vue still host our application, just like we write a normal single page application

Step 1: Create a client entry

Let’s create a new cliententry. js file as the client bundle entry file, as follows:

Webpack is then configured and packaged to generate bundle.client.js

Niceties: Because the server and client have different goals, is that why you need clientEntry and serverEntry entry files

Step 2: Let Vue host the client

After bundle.client.js is generated, all we need to do is put this file in the script tag of the page and return it directly, just like the index.html in our single page application, which inserts the packaged JS file, so let’s modify server.js. Insert bundle.client.js into the page he returns

At this time to click on our link, we find that the page has no longer sent requests to refresh the page, thus achieving our second goal

At this point, the server-side rendering of a single page is almost complete

Points to consider:

  1. Serverentry. js should be packaged as bundle.server.js before it can be used in server.js

  2. How to implement nuxt-like configuration of page title and description? (context)

  3. For the content returned by the server above, could it be put into a template file? Would it be better to import a template file? (JS rendering engine)

To sum up: We have basically realized the process of single-page server rendering, but there is still a very important part missing, that is the acquisition of dynamic data (network interface data).

Step 3: dynamic interface data support

Let’s start with the server entry file

Renderer. RenderToString = resolve(app) {renderer. RenderToString = resolve(app) {renderer. We can add a custom method inside the component that is dedicated to dynamically retrieving data. We call this method beforeServerRender, it returns a promise. We also need to consider how to use dynamically retrieving data in the component. In this case, we can use vue-store to achieve this (here is why). Modify serverentry. js as follows

Next let’s add a test interface to server.js

Then modify helloWorld.vue

Small points: The vUE lifecycle is: Create a new vUE instance object and initialize the default declared cycle functions and default events. Go to beforeCreate() and create the new vue instance object for both data and methods. Create() creates a new vue instance object for both data and methods. The data in data and methods is initialized. In other words, the beforeServerRender function is in a phase where data is fetched only after creation. Vue instance ->beforeServerRender->beforeCreate->created, create, create, create, create, create, create, create, create, create, create, create, create App. store is in the beforeCreate phase, so we need to pass the app.store parameter to the beforeServerRender function. BeforeServerRender userInfo is not retrievable from store and this. Data is not retrievable beforeServerRender userInfo is not retrievable from store and this. Data is not retrievable from store. BeforeServerRender does not modify userInfo directly, it is not retrievable in store, this. Data is not retrievable in beforeServerRender, it is not retrievable in store, it is not retrievable in this. Rather, it’s done through store and computed attributes

Modify store.js as follows:

When the page is refreshed, the following problem occurs: there is data in the source code, but the page is not displayed

Specific reasons are as follows: The server vue instance is not the same as the client vue instance. The server is not the same as the beforeServerRender function. This function assigns a value to the store of the server, but the store of the client has a value, but the store of the client has a value, and the userInfo in the store of the client is empty, thus causing the above problem. How do you solve it? $store = $store = $store = $store = $store = $store

Step 4: Synchronize server $store to client

How do you synchronize? When we render the template, we assign this object to a global object window.INITIAL_STATE, and then read the value on the client side to restore it. Okay, let’s go through the process of modifying the file

Modify serverentry. js as follows

Modify server. Js

Modify clientEntry. Js

At this point, regenerate bundle.server.js and bundle.client.js, restart the service, and refresh the browser

As you can see, the objective has been achieved. At this point, we’ve accomplished both of our original goals for single-page server rendering

Code global directory

If you need to download the code, you can download it directly

Supplementary problems

  1. Why does the server create a new instance for each request?

    After a server service is started, it runs all the time. If an instance is kept in the memory, data contamination may occur. For example, with userInfo in the store above, problems can occur if multiple users access the same user information page

  1. What is the difference between server-side rendering and pre-rendering?

    If you are researching server side rendering (SSR) to improve SEO for a few marketing pages (e.g. /, /about, /contact, etc.), then you may need pre-rendering. Instead of using a Web server to compile HTML dynamically in real time, you use pre-rendering to simply generate static HTML files for specific routes at build time. Summary: Pre-rendering is to build the page in advance, server rendering is dynamic real-time rendering, if the page content is little change, you can use pre-rendering, if often change or need to dynamically fetch and read the database content, you can use server rendering

  1. What are the pros and cons of server-side rendering?

    Advantages:

    1. In addition to seo benefits mentioned above, server-side rendering can speed up the display of first-screen content

    Disadvantages:

    1. The immediate problem with rendering on the server side is that it becomes more stressful on the server
    2. Can only be used in certain lifecycle hook functions due to development constraints
    3. The deployment must be in the Node.js server running environment
  1. Why is server rendering faster on the first screen

    If the above is really understood, I’m sure you are smart enough to understand why

  1. One problem I encountered: Here is a simple service that provides an interface that is requested 2 seconds later and prints the results

Surprisingly, the result is an error, indicating a timeout, and an access exception

I used the browser to access: normal

Finally I found the answer on the document:

If you do not write host, an unused internal IP address will be used at random, which explains why the timeout occurred, and why the above exception message is 10.33.42.50

So, revise it as follows

conclusion

To sum up, this is my understanding of single-page server rendering. I can justify myself, but it does not necessarily mean that it is right. Please distinguish according to your own knowledge.