An overview of the
Before, I did a React project and a Vue project. Without any optimization, the average loading time of the first screen of these two projects actually reached 20+s, which could be 10s or almost 30s, which was totally unbearable. Optimization was imperative. The optimizations for the React project will be added later.
The above picture is the homepage of Vue project. The whole project is built by VUE-CLI and mainly divided into 4 modules, as shown in the left navigation bar of the page. The total code quantity is not too large, and there are about 50 components in total.
The first thing to determine is what is causing the first screen rendering to be so slow? Open the Chrome Network panel, check the Disable cache option, refresh the page to observe the loading of resources, and find that the culprit is app.js and Vendor. js generated by Webpack, where the size of vendor.js reaches 1.2m and the download time is more than 20 seconds. App.js is also fast at 1M, while manifest.js is not very big. Vendor.js mainly combines modules used in node_modules into one JS, so it is quite large. We also want to package business code and third-party references separately. Manifest.js contains the Webpack Runtime code and module manifest code, which is used to prevent third-party library files from being packaged because the code has been modified but not the third-party library files. A search on the Internet, found that the optimization point is mainly in the following aspects:
- The Gzip compression function is enabled
- The introduction of the CDN
- Route lazy loading
- Some third-party components load on demand rather than all
- Smaller image resources are embedded in SRC in Base64 to reduce HTTP requests
The specific optimization
Gzip compression
Gzip is the abbreviation of GNUzip. It was first used for file compression in UNIX systems. Gzip encoding over THE HTTP protocol is a technique used to improve the performance of Web applications, and both web servers and clients (browsers) must support GZIP. Chrome, Firefox and Internet Explorer all support this protocol. Common servers such as Apache, Nginx, IIS also support gzip compression efficiency is very high, usually can reach 70% compression rate, that is, if your web page has 30K, after compression becomes about 9K
I use Express for the backend. It is very easy to start Gzip. First, NPM install Compression to install middleware, and then add use to app.js to use:
var compression = require('compression');
var app = express();
app.use(compression())
Copy the code
Restart the service and observe the Response Header in the network panel. If you see the following fields in the red circle, it indicates that GZIP is successfully enabled
The introduction of the CDN
CDN(Content distribution Network) is a kind of public service, which has many servers located in different regions and connected to different operators. The so-called USE of CDN essentially means that CDN is used as the front of the website, and users access the CDN server instead of the website directly. Due to the optimization of TCP in CDN, the cache and prefetch of static resources, and the intelligent allocation of users to the nearest node when accessing CDN, a large amount of delay is reduced and the access speed can be greatly improved
One principle is to try to put large third-party libraries on CDN to reduce the request time. In my project, I put Vue,vuex, VUE-Router and Echarts on CDN. To do this, open BootCDN and search for keywords and copy the link to the body closing tag of index. HTML, as shown below
externals: {
'vue': 'Vue'.'vuex': 'Vuex'.'vue-router': 'VueRouter'.'echarts': 'echarts'
},
Copy the code
After using CDN, the advantages are huge. Observing the Network panel, the time is almost under 50ms
Route lazy loading
Lazy route loading is also called lazy route loading. It is loaded on demand. Single-page applications, such as the vue without application of lazy loading, using webpack files will be unusually large after packaging, enter the home page, the content of the need to load too much, time is too long, there will be a long time of white, even if done loading is also conducive to the user experience, while use lazy loading page can be divided, Loading pages when needed can effectively share the load pressure of the home page and reduce the load time of the home page. An example of Vue’s official website is shown below, with asynchronous components combined with Code-splitting from Webpack
So in the project, go to the router’s index.js and change the import Comp from ‘@/component/ XXX ‘to the following, leaving the vue-router configuration unchanged
// Asynchronous component, route lazy loading
const BookMark = resolve= > require(['@/components/BookMark'],resolve);
const HotBookMark = resolve= > require(['@/components/HotBookMark'],resolve);
const ImportBookMark = resolve= > require(['@/components/ImportBookMark'],resolve);
const Default = resolve= > require(['@/components/Default'],resolve);
Copy the code
After packaging, you can view the files in the JS folder. Each lazy component generates a JS, as shown in the red box below
Third party load on demand
For example, the Echarts used in this project only uses one bar chart component and the rest are not used, but the whole Echarts will be put into the package after import packaging, resulting in a waste of space
import echarts from 'echarts'
Copy the code
Therefore, you only need to import the components used, as shown below, which saves a lot of unnecessary volume
import echarts from 'echarts/lib/echars'
import 'echarts/lib/chart/bar'
import 'echarts/lib/component/legend'
import 'echarts/lib/component/title'
Copy the code
Pictures turn base64
Small images can be converted to base64 strings and embedded in img SRC to save the number of HTTP requests. Webpack uses urL-loader for processing, and Limit controls the threshold for transferring images to Base64. If the threshold is smaller than this value, the image will be transferred to Base64
{
test: /\.(png|jpe? g|gif|svg)(\? . *)? $/.loader: 'url-loader'.options: {
limit: 10000.name: utils.assetsPath('img/[name].[hash:7].[ext]')}},Copy the code
Optimized performance
After the above optimization, the opening time of the home page drops rapidly. DomContentLoaded takes less than 1s, and load takes less than 4s to be fully loaded. What takes more time is several large background pictures, which are already large in volume
This is the initial optimization strategy, which will be further optimized. Ps: WebPack-Bundle-Analyzer is a powerful tool that can effectively analyze the volume occupied by packages. The following is the final optimized package structure diagram. The original package structure diagram is much larger than the following, mainly echarts, Vue, Vuex modules
The optimized package after gzip size pleasing ~