SSR: when, why and for what. On the example of Vue

  • Tutorial

( Illustration )

Once upon a time A few years ago, when I first started working with the web in Java, we worked with JSP. The whole page was generated on the server and sent to the client. But then the question arose that the answer came too long ...

We began to use an approach in which an empty page template is given, and all the data were gradually loaded by Ajax. Everyone was happy, the pages were shown. So far we have not understood what we have done for the collar, as CSR adversely affects search engine optimization and performance on mobile devices. But then I again heard about support for SSR JS frameworks.

And what happens is history repeats itself?

What are the principles of SSR?

1. Prerendering. In the simplest case, N HTML files are generated, which are put on the server and returned as they are - that is, static is returned, we do not generate anything during the request.



2. As in the case of JSP, full HTML with all content is generated on the server and returned to the client. But in order not to generate a page for each request (of which there may be a million and our server will be bent), let's add a proxy cache. For example, varnish.



When can each of these methods be applicable:

1. When does it make sense to generate a pack of HTML files? Obviously, in the case when the data on the site change less often than never. For example, the corporate site of a shoe repair stall that is around the corner (yes, the uncle who changes the taps in a 2x2 meter stall also wanted the company's website - and, of course, with the company's mission page). For such a site, you don’t need to bother about frameworks, SSR and other whistles at all, but this is a spherical example. What if we have a blog in which 1k posts? Sometimes we update them, sometimes we add new ones. Generate 1k + static files ... Something is not right. And if we change the post, then we need to regenerate a certain file. Hmm ...

2. And here we have the second method. Where we generate the first time on the fly, and then we cache the answer in the proxy service. Caching time can be an hour / two / day - whatever. If we have 10,000 visits per hour to the post (unbelievable, right?), Then only the first request will reach the server. The rest will receive a cached copy in return, and our server is more likely to live. In the case of updating some post, we just need to reset the cached entry so that the next page is generated on the next request.

From words to deeds:


Hello world repo.

0) generate hello world

For a quick start, the Nuxt community has prepared basic templates , you can install any of them with the command:

$ vue init <template-name> <project-name>

By default, the proposed start-template, and take it for our example. Although in the real application we chose express-template. Let's call the project plainly:

$ vue init nuxt-community/starter-template habr-nuxt-example
$ cd habr-nuxt-example
$ yarn # или npm install, как будет угодно
$ yarn dev

Whose , we generated hello world. Turning on urla, you can see the generated page:
1) Webpack and Linting

Nuxt out of the box has customized webpacks with support for ES6 (babel-loader), Vue single-file components (vue-loader), as well as SCSS, JSX and so on.

If these capabilities are not enough, the webpack configuration can be expanded. We go to nuxt.config.js, and in build.extend we have the ability to modify the config.

For example, let's add lint styles by analogy with lint code - an important, in our opinion, point for maintaining a uniform code base. This is a good habit that will help avoid many pitfalls.

An example of a config extension (connecting a config file for a virgin based on an environment variable):

config.plugins.push(
 new StylelintPlugin({
   files: [
     '**/*.vue',
     'assets/scss/**/*.scss'
   ],
   configFile: './.stylelintrc.dev.js'
 })
)

The remaining changes can be viewed in the repo tag , these changes will help us keep styles in order.

And an example of a config file linter: use Standard JS, as is common in Vue / Nuxt solution:

...
 extends: [
-    'plugin:vue/essential'
+    'standard',
+    'plugin:vue/recommended'
 ],
…

2) For the example of working with data, we will use this API : We will

connect Axios as a plugin, create a new file in the plugins directory:

import * as axios from'axios'let options = {}
// The server-side needs a full url to worksif (process.server) {
 options.baseURL = `http://${process.env.HOST || 'localhost'}:${process.env.PORT || 3000}`
}
exportdefault axios.create(options)

And an example of use:

import axios from'~/plugins/axios'exportdefault {
 async asyncData ({ params }) {
   const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
   return { data }
 }
}

The rest of the turnips on the tag .

Download figures:

1) SSR + Varnish

First request:



Second:



2) No-ssr



Second request from fast The



blank page came quickly, but it took 2 seconds to generate content on it.

Conclusion


What is the result? We figured out how to get a minimally configured running SSR application. They added Linting to preserve the style of the code from the very beginning of the project’s life, and also outlined the common architecture. You can write your googol.

Also popular now: