When you develop a front-end project that gets up and running, but the first visit is incredibly slow, don’t people wait a few seconds and think there’s something wrong with the site? Of course it will, and then the user will close the page, joking: What site, can’t access it. But in fact, it is not inaccessible, but requires users to wait a second to a few seconds, can be almost no one is willing to wait.

For front-end projects, front-end performance optimization is essential. The good news is that there are a lot of good tools out there to help us achieve this, such as various build tools: WENpack, Gulp, Grunt, etc., and the official scaffolding of the major front-end frameworks has quietly done a lot of performance optimization.

Project background

About two months ago, I launched my personal blog. The whole project includes: blog front-end based on next.js, blog management background SPA based on React, and middle platform interface based on egg.js. I later developed a vUE version of the blog front desk (SPA, of course) using vue.js, and I decided to try to optimize performance based on the VUE I was more familiar with.

My personal server configuration: 2M bandwidth, win2008Server. Blog front-end VUE version problem: the first screen loading is very slow, about 4~8s. Interface access speed: It takes about 4 seconds for some interfaces to be received (interface optimization is not performed here).

Obviously, the 2M bandwidth results in slow loading of front-end resources and slow interface requests, but that doesn’t change. So, I need to optimize from the project itself.

Open dry

When I was actually optimizing, I didn’t analyze it, so IT took me a bit of a headless chicken. As a concluding article, I will analyze it by project. First of all, the project is a vue.js based development SPA (single page application), which means it will load most of the resources on the first screen, resulting in slow loading on the first screen, but fast opening of subsequent pages at the same time. As you can easily see from Chrome, the following files are requested when the page first loads:

Apparently, the various dependencies in the project were packaged into these two files by the Vue scaffolding, which took 4-8s to compress to a size of over 400 KB from the server. At the same time, request the remaining resources only after the two files are completed. There are two ideas:

  1. Breaking them up into multiple files, asynchronously downloading multiple files smaller files is faster;
  2. Load the dependencies used in the project through CDN;

Finally, I used CDN to load the resources used in the project (the first method was not successful). Before that, I configured the BundleAanlyzerPlugin in vue.config.js to analyze the situation of each resource after packaging. Of course, vuecli3/ Vuecli4 can use the command vue UI to open the intent graphical interface. When packaging through the graphical interface, you can also see the size and loading speed of various resources after packaging through the dashboard in the interface.

Large dependencies in the project can be found through the analysis interface generated by BundleAanlyzerPlugin or the graphical interface generated by Vue UI. Problems can be solved by introducing these dependencies through CDN. Specifically, you need to add the following configuration to the configuration file:

externals: {
  'vue': 'Vue'.'axios': 'axios'.'marked': 'marked'.'vue-router': 'VueRouter'.'ant-design-vue': 'antd'.'moment': 'moment'.'highlight.js': 'hljs'
}
Copy the code

The first is the dependency package name, followed by the object name used after introduction. In the dependency above, moment is dependent on ant-design-vue, so you need to configure the MOMENT into the CDN even if it is not used in the code. First, find some sites that offer public CDN services: bootcdn.cn is used here. However, bootcDn.cn does not provide CDN resources for the latest version of Ant-design-vue (here [email protected]). So I went to jsdelivr.com, another public CDN site, to obtain the CDN resources of Ant-Design-Vue.

Bootcdn.cn simply searches for the relevant NPM dependency name, and it lists the relevant primary resources. Jsdelivr.com lists all the resources of the entire dependency package and provides the CDN service uniformly, so you need to start by finding the main dependency file of Ant-Design-Vue: Antd.min.js and antD.min.css are located in the dist directory (this is also my first time using them, so it’s a little bit of a sideshow).

After obtaining the dependent CDN resources (including JS and CSS), we need to introduce them into the static resources of the project and into public/index.html. It should be noted that the CDN resources of VUE should be introduced first, because the subsequent dependencies are based on VUE. If they are introduced later, the dependencies may not take effect. Second, dependencies introduced in the project via import also need to be removed, such as the code loaded on demand for ant-design-vue above.

After being introduced through CDN, relevant dependencies can be quickly obtained through externally provided CDN resources without occupying the bandwidth resources of the server, and the dependencies in the project become small after being packaged:

Dependencies that would have taken 4-8s to load are loaded in 1s. As you can see, the 30.7KB resource above takes 800ms to load from my server, and the 34KB resource via CDNtakes 53ms. The loading speed of the first screen has been solved, at least the time of the white screen on the home page has been greatly shortened; Next we need to deal with the processing of image resources in the project.

It would be best if all resources could be added via CDN, but what if not? The first is that some resources may not allow this (clients do not), and the second is that these services may be charged. The pictures on the website can be accelerated through the image CDN service provided by Seven Niuyun, some service providers charge, there are free, here please try yourself. Here we try to optimize at the code level. In my blog, the home page will load two pictures of website advertising resources (each size is about 240KB), which can be loaded quickly through my server. Since images are network resources outside the project, they cannot be interfered with by construction means, so we can only optimize them at the code level. I use a dependency called VUe-lazyLoad, which allows lazy loading of images. Lazy loading: Resources are loaded when they are in the viewable area of the browser. That is, resources are loaded slowly to reduce server stress.

Vue-lazyload is registered globally as a plug-in in main.js, and can then be used globally to provide v-lazyload and other directives.

Vue.use(VueLazyload, {preLoad: 1.3, error: require('./assets/images/404.png'Loading: require() loading: require('./assets/images/lazyloading.gif'Attempt: 1}Copy the code

In the configuration, I configured loading images and alternative images that failed to load, which need to be prepared by the developer. Note here that loading and error images may not be loaded if the developer uses webpack plugins related to image processing. For example, images will be converted to Base64.

Vue-lazyload is a dependency library developed by Chinese people, with powerful functions and many usages. Here’s a quick example of basic usage:

// Use <img V-lazy = in the img tag"..."/> // Use <div V-lazy: backound-image = as background image"..."> </div>
Copy the code

For more on this use, be sure to refer to the official documentation: vue-lazyload.

If the interface request is slow and the image is in the viewable area from the beginning, then the image has not been loaded (the interface has not finished the request). The image processed by V-LazyLoad will display the error image, and the image will be loaded again after the interface request is finished. This clearly does not meet expectations, and v-LazyLoad is not suitable for this situation.

Of course, static image resources in the project can also be processed by webpack-related plug-ins or loaders. Here I use imagemin-webpack-plugin, which can process images during project construction and reduce the volume of image resources by reducing the quality of images. I used it briefly in my project:

const ImageminPlugin = require('imagemin-webpack-plugin'// Plugins in webpack plugins: [new ImageminPlugin({test: /\.(gif|png|jpe? g|svg)$/i,disable: false, // Disable during development
    pngquant: {
      quality: '80-90'}})]Copy the code

Note that when other image-processing plug-ins are used at the same time, this plug-in should be placed after other image-processing plug-ins.

For more detailed usage and configuration, please refer to the official documentation: Imagemin-webpack-plugin.

In fact, I also spent some time on other related processes while modifying these configurations. Here are some personal lessons for you to take into account. In my project I used Sass to write style code, and the dependency library for handling Sass is Node-sass. There are two dependencies that can handle sASS compilation problems: Node-sass and Dart-sass. Although Node-sass has a number of problems with its use, I chose it for two reasons:

  1. Dart-sass compiles fast in Dart, but much slower in Node.js than Node-sass;
  2. Dart-sass, known as SASS on nPMJs.com, was last submitted 3 years ago and last submitted a month ago.

However, using Node-sass can be troublesome. First of all, there are installation problems. CNPM is recommended. Second, it has requirements for nodeJS versions, which must be noted:

NodeJS Minimum node-sass version Node Module
Node 14 4.14 + 83
Node 13 4.13 + 79
Node 12 4.12 + 72
Node 11 4.10 + 67
Node 10 4.9 + 64
Node 8 4.5.3 + 57

Therefore, if the local node.js version does not match the server node.js version, the installation will not succeed. My development computer is Win10, so it is not affected, but the server is Win2008 server, and higher versions of NodeJS cannot be installed on this server. Of course, Linux servers are not affected.

# # # #

Since my project is built by the latest version of VUE-CLI, the official scaffolding of VUE, VUe-CLI does a lot of configuration optimization based on WebPack4 by default, and WebPack4 itself also provides a lot of optimization capabilities by default, which do not need personal configuration; So there’s only so much optimization I can do within my personal scope. To sum up, there are only three:

  1. Using CDN resources to replace the dependent package, reduce the size of packaged dependent package;
  2. throughvue-lazyLazy loading network pictures;
  3. throughimagemin-webpack-pluginCompress image resources in the project;

Of course, as mentioned earlier, network images can also be processed through the CDN acceleration service provided by the server vendor.

Look up at the sky, down to earth; Avenue to simple, do not forget the original purpose. Knowledge lies in the accumulation of little by little, the great god also needs to build brick by brick, to become a top person in any technical field, persistence and accumulation are necessary, I hope you and I encourage each other.