background

A few days ago, I made a small tool for web speed measurement according to the demand. After consideration, I made some selection. Since react has been used to move blocks in the company, I decided to improve my all-round ability this time, contacting and using VUE to build a small project, which was only about 33KB after compression with GIZP. With axios and prerender-SPa-plugin and business code, the compression is less than 50KB and the user experience is good.

I didn’t use VUE many times, so I looked up all kinds of data, but I felt that the process was not smooth. From my experience, the average data provided by VUE online was far inferior to those provided by React, and I had some problems, especially prerender-SPa-plugin, which was not mentioned online. So I shared my harvest and made a contribution to VUE.

origin


Add a note: prerender is to render once in advance at compile time, and the server side render SSR is to fill in the corresponding content every time the user requests the server (the two are essentially different, please note!).

The installation

Since this small project is independent, I do not need to consider the version of NPM package, so I directly run the whole environment on the latest vuecli3.0. But to be honest, the scaffolding of vuecli3 gives me a terrible experience, the original webpack configuration is hidden. It took a while to install prerender-spa-plugin using NRM to cut to CNPM, but it was always stuck in the place where puppeteer was installed. The prerender-spa-plugin relies on puppeteer, which downloads the latest version of Chromium, Google’s headless browser kernel (about 200M+), so if you can’t surf the web properly, you’ll get an error. I used the lantern to wait for a long time to download, version 72, so it is important to often climb the wall 😅

The principle of

Puppeteer is a Google plugin that enables a wide range of browser automation applications such as crawlers and test automation. The prerender-SPa-plugin relies on puppeteer to operate on chromium, the real browser kernel, which runs through the SPA and generates static HTML with the DOM nodes and data already filled in. In order to return XHTML documents with content directly to the user, I ran through a browser ahead of time, generating index.html(along with routing) and other documents after running through JS and CSS. This has two drawbacks. First, it cannot display the user’s own content. Second, it is not suitable for large projects with many dynamic routes. Once you understand the principle, you can use 🙂 at ease

configuration

The first thing to note is that you should set the vue-router mode to history, but if it is a root path and there is no subordinate route, Vue-router will be compiled without introducing vue-router…

vue.config.js
The official MD
vue.config.js

const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
Copy the code

Then the module exports

configureWebpack: {
        plugins: [
            new PrerenderSPAPlugin({
                staticDir: path.join(__dirname,'dist'),
                routes: ['/'],
                renderer: new Renderer({
                    inject: {
                        foo: 'bar'
                    },
                    headless: false,
                    renderAfterDocumentEvent: 'render-event',
                    //renderAfterTime: 5000,
                    //renderAfterElementExists: 'my-app-element'})}),...Copy the code
  • Dist in staticDir is the output folder name, needless to say
  • Routes is the route that you want to pre-render. Here I only need to pre-render the root route. There are other routes that can be added to the array
  • Renderer pre-renders provide three timing implementations, renderAfterDocumentEvent, renderAfterTime, and renderAfterElementExists

RenderAfterDocumentEvent and renderAfterTime are common, which simply means that one prerenders after an event, the other prerenders a few seconds after loading, If you’re using renderAfterDocumentEvent it needs to be implemented in the vue lifecycle

mounted: function(){
            document.dispatchEvent(new Event('render-event'));
        },
Copy the code

After this configuration, the plugin will automatically call the Chromium kernel to fill the HTML in the route each time the build is packaged. To see the difference, you can use Chrome preview to check that it is not pre-rendered.

This is done, the level is limited, write not deep enough, thank you for reading!