Vue project package compression: make the page respond faster

Time:2020-5-19

This article is published on my personal website: http://wintc.top/article/34. Please indicate the reprint.

There are many factors that affect the response speed of web pages, such as: too many HTTP requests, too long for the server itself to process the request, too much request content, too long for JS script execution, browser reflow and redraw, etc. The response speed of the website page is closely related to the user experience, which directly affects whether the user is willing to continue to visit your website. For Vue projects, the most common problem may be that the packaged file is too large, resulting in long load times.

One of my small projects has only three or four pages, but because the server bandwidth is too small and the loading time is too long, the problem is particularly obvious. So I optimized it by using lazy route loading and gzip compression, and the access speed has been significantly improved.

1、 Route lazy loading: splitting code blocks

Vue supports asynchronous components, that is, a promise can be used where the component is used, and promise will eventually return a component object through resolve. The dynamic import method of webpack allows the code to be packaged in blocks and returns a promise (exactly what asynchronous components need). In the routing configuration table, you can use import to divide each page component into different code blocks, and then load the corresponding components when the route is accessed, so as to avoid packing all content in one chunk, so as to “load on demand” and greatly improve the response speed.

Route configuration mode without dynamic loading:

// router.js
import VueRouter from 'vue-router'
import Vue from 'vue'
Vue.use(VueRouter)

import Home from '@/pages/Home'
import Tree from '@/pages/Tree'
import SearchHighlight from '@/pages/SearchHighlight'
import Watermark from '@/pages/Watermark'

export default new VueRouter({
  routes: [
    {
      path: '/',
      component: Home,
      children: [
        {
          path: 'tree',
          name: 'Tree',
          component: Tree
        },
        {
          path: 'search-highlight',
          name: 'SearchHighlight',
          component: SearchHighlight
        },
        {
          path: 'watermark',
          name: 'Watermark',
          component: Watermark
        }
      ]
    }
  ]
})

Execute yarn build (or NPM run build) package, and check JS and CSS in dist folder:

Vue project package compression: make the page respond faster

You can see that there are two files under JS and CSS respectively after packaging. The chunk vendors file contains all the page JS or CSS files, with the sizes of 769k and 270k respectively. Now modify the routing configuration and use dynamic loading component to package. Let’s see what the package file looks like.

Import components in the form of () = > Import (‘xxx ‘):

// router.js
import VueRouter from 'vue-router'
import Vue from 'vue'
Vue.use(VueRouter)

export default new VueRouter({
  routes: [
    {
      path: '/',
      component: () => import('@/pages/Home'),
      children: [
        {
          path: 'tree',
          name: 'Tree',
          component: () => import('@/pages/Tree')
        },
        {
          path: 'search-highlight',
          name: 'SearchHighlight',
          component: () => import('@/pages/SearchHighlight')
        },
        {
          path: 'watermark',
          name: 'Watermark',
          component: () => import('@/pages/Watermark')
        }
      ]
    }
  ]
})

Execute yarn build (or NPM run build) package, and check JS and CSS in dist folder:Vue project package compression: make the page respond faster

There are four more chunk – * files in the JS and CSS folders, just corresponding to the four components we introduced dynamically. In this way, when we visit a page, we will load the chunk – *. JS and chunk – *. CSS corresponding to the page. Observing the file size, the core JS file chunk venders size has been reduced from 769k to 725k, because my four page codes are very simple, and it seems that the optimization effect is not great. However, in a large project with many pages, the optimization effect will be very obvious, so will the CSS part.

2、 Compress request resources

1. Principle introduction

Every day when we use the online disk, uploading a large folder must be very slow. At this time, we will compress it into a compressed package. When we need to download it, we can download it and decompress it, which saves a lot of time for uploading and downloading. The same principle can be used for network requests. When we request a resource from the server, such as JS or CSS files, the server compresses the file, and then returns it to the browser. After the browser operation is decompressed, it can be used.

First of all, when the browser sends the request, it will inform the server through the request header accept encoding, which encoding format resources the browser supports. Open the browser’s network to view the request header of a request of the current web page:

Vue project package compression: make the page respond faster

The value of accept encoding indicates that the browser supports the encoding format generated by gzip or the encoding format generated by deflate compression algorithm. This tells the server that it is OK to compress the requested resources with these two methods. Accept encoding may also have the default format of compress and identity uncompressed.

If the server compresses and encodes the resource, it will tell the current request what encoding format is used through the response header content encoding. Of course, if the server does not do this, it will not return this response header. For example, a request compresses the returned content with gzip:

Vue project package compression: make the page respond faster

2. Server configuration

Generally, when we deploy to the server, we will use nginx as the proxy server, and all requests will be forwarded through nginx. Here, we will demonstrate how nginx configures gzip compressed files before returning. Before configuration, take a look at the online requests of sample projects:

Vue project package compression: make the page respond faster

It can be seen that the chunk vendors file generated previously has a size of 725k, a request time of 7.10 seconds, and a download time of 7.05 seconds, which is too slow. Configure nginx and open gzip:

server {
        gzip on;
        gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
}

The function of this configuration is to use gzip to compress the content types listed in gzip ﹐ types returned by nginx server (provided that the requester supports gzip, of course). Execute sudo nginx – s reload to make this configuration take effect. At this time, refresh the previous page to see the effect:

Vue project package compression: make the page respond faster

For the same request, the size of the requested content becomes 216k, and the download time is directly reduced to more than 1s, with remarkable effect! Nginx also has other configuration items of gzip. For example, gzip can be used to control the compression rate (higher compression rate may mean greater server consumption), and interested students can view nginx documents.

3. Gzip compression is used directly when packaging web pack

In the previous step, the returned content was compressed with gzip when requesting the server. When there is such a problem, repeated compression for different requests of the same resource will undoubtedly increase the CPU and memory consumption of the server. With webback, we can directly use the compression webback plugin plug-in to compress our code. First install compression webpack plugin to dev dependency:

//Yarn installation
yarn add compression-webpack-plugin -D
//Or NPM
npm install compression-webpack-plugin --save-dev

Simple configuration, more configuration can be found in the official document: compression webpack plugin:

const CompressionPlugin = require('compression-webpack-plugin')

module.exports = {
  // ...
  configureWebpack: {
    plugins: [
      new CompressionPlugin({
        Test: / \ (js| CSS)? $/ I, // which files should be compressed
        Filename: '[path]. GZ [query]', // compressed filename
        Algorithm: 'gzip', // use gzip compression
        Minratio: 1, // compression rate less than 1
        Deleteoriginalassets: true // delete the uncompressed file. Set it carefully. If you want to provide non gzip resources, you can set it to false or not
      })
    ]
  }
}

Take a look at the JS and CSS folders under dist. now the files are compressed into. GZ:

Vue project package compression: make the page respond faster

After compression, chunk vendors is only 176k, which is nearly 80% compressed compared with the original 725k. You can also use this method to compress images and fonts, as long as you modify the regular expressions of test configuration items to match such files. But now, you need to configure static compression in nginx server:

server {
    gzip on;
    gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
    
    gzip_static on;
}

After gzip ﹐ static is set to on, if there is a “resource path. GZ” file when accessing resources, it will be returned directly, and its priority is higher than the dynamic gzip. Now visit the following page:

Vue project package compression: make the page respond faster

If you hover your mouse over the size of chunk vendors, you can see the prompt “176kb transferred over network, resource size: 724k”. If the request resource file of your project is too large, you can try gzip and other compression methods, which will have an immediate effect.