background

The last article talked about the first screen optimization, for the specific article see mobile SPA Mall optimization record (I) — first screen optimization, this time to share some optimization experience of packaging speed, because in the actual project development, with the continuous increase of the project, the increasing number of dependencies, we will find that the speed of Webpack packaging will be slower and slower, Sometimes NPM run may take enough time to go to the bathroom. In this era of rapid development, such a slow pace is not allowed. This article takes the company’s SPA mall as an example to introduce the experience of optimizing packaging speed in detail.

start

The starting template of this project is the Webpack template of VUe-CLI. There will be about 30 pages when the project is completed. The packing time before optimization is shown as follows:


Next, optimization began, which was mainly divided into four aspects: reducing the number of packaging files, reducing unnecessary function overhead, optimizing the packaging method, and upgrading the packaging tool.

1. Reduce the number of packaged files

Guiding principle: Less things to pack will naturally speed up.

1.dll

Webpack. DllPlugin + webpack DllReferencePlugin this set of plug-ins should be borrowed from the ideas of the DLL so DllPlugin this name, purpose is to vue, vue – the router, the react, jquery etc. The volume is larger, The third-party packages that are not updated frequently in the project are removed and packed separately, and then told Webpack that I have packed these packages before, you can use them directly every time you pack them, and you don’t have to repack them every time.

Usage:

  1. Create a new webpack.dll.conf.js folder in your build folder and write it like this:
const path = require('path')
const webpack = require('webpack') module.exports = {entry:{// Where do you want to export dependencies vue:['vue'.'vue-router'}, output:{path:path.join(__dirname,".. /src/dll"),
        filename:'[name].dll.js',
        library:'[name]'New webpack.DllPlugin({path:path.join(__dirname,".. /src/dll".'[name]-manifest.json'),
            name:'[name]',
        }),
        new webpack.optimize.UglifyJsPlugin()
    ]
}

Copy the code
  1. performwebpack --config build/webpack.dll.conf.jsPackaging generates the extracted common package.

    At this point you should see the DLL directory and the generated public package JS and JSON under SRC.
  2. DllReferencePlugin is configured in the normal WebPack configuration file for association
Plugins: [new webpack DllReferencePlugin ({/ / write step created a json path here manifest: require ('.. /src/dll/vue-manifest.json')})... ]Copy the code

Now, it’s time to pack again, and the more third-party packages you extract, the better the speed of packaging will be. If you want the packed HTML to automatically import the dL. js file from the second step, you can use add-asset-html-webpack-plugin or modify the configuration of HtmlWebpackPlugin to automatically import the DL. js file into the packed HTML.

Add-asset-html-webpackplugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin Add – asset – HTML – webpack – plugin configuration

In addition, the CDN import package and externals configuration can also be used. The idea is the same as that of DLL, which is to extract the third-party package and only package the service code, but in this way, the third-party package directly references the CDN.

2. Reduce unnecessary resolve

  1. Take a look at each rule in Webpack to see if there is any extra resolve in include or exclude the node_modules folder.
  2. Where you use babel-loader, remember to set cacheDirectory to take advantage of bable’s cache.
  3. The Extensions in Resolve can remove unnecessary suffix autocomplete and reduce webPack query time, for exampleextensions: ['.js', '.vue', '.json','.scss','.css'],Writing so much autocomplete saves the suffixes when writing code, but it adds time overhead to automatically query the suffixes when Webpack is packaged.
  4. Use full paths instead of directory names when importing, for exampleimport './components/scroll/index.js'Rather thanimport './components/scrollTo reduce the webpack path query.

2. Eliminate unnecessary feature overhead

Guideline: Reduce the amount of extra work you have to do during the packaging process

Our goal is to optimize the packaging speed, so that unnecessary functions that are not related to this can be paused and turned on later.

Close the Source Map.

Sourcemap has the following configuration values:

eval: Generate code for each module byevalExecute, and there is at signsourceURL cheap-eval-source-map: Converts code (inline) to each module byevalExecute, and sourcemap acts asevalDataurl cheap-module-eval-source-map: the original code (inline only) works the same way, but with higher quality and lower performanceeval-source-map: the original code is the same, but with the highest quality and lowest performance. The sourcemap generated by the conversion code (inline) has no column mapping, and the Sourcemap generated from loaders is not used with cheap-module-source-map: the original code (inline only) is mapped from the Loader as above except for each line characteristicsource-map: The sourcemap quality of the best raw code has complete results, but will be slowCopy the code

When we don’t need debugging, we can speed up the packaging by turning sourcemap off or lowering its level.

3. Optimize packaging: parallel

Guideline: Parallel packaging speed is of course fast.

1. UglifyJSPlugin parallel

This is easier to configure, UglifyJSPlugin plugin under the attribute parallel set to true.

new UglifyJSPlugin({
        parallel: true. })Copy the code

You can also set up a packaged cache, as described in the configuration below

2.Happypack

Happypack uses a multi-process model to speed up code building. For example, we used to use vue-loader to process Vue files. We used to process vue files sequentially. Now we can use Happypack to process Vue files in parallel.

  1. First, install HappyPack

    npm install --save-dev happypack
  2. Modify the webpack. Base. Config. Js
const HappyPack = require('happypack');
const vueLoaderConfig = require('./vue-loader.conf')
exports.module = {
  rules: [
    {
      test: /\. Vue $/, //vue-loader replaces happypack/loader with happypack/loader.'happypack/loader? id=vue'
    },
    {
        test/\.js$/, //babel-loader replaces happypack/loader with happypack/loader.'happypack/loader? id=js'}... ] }; Exports. plugins = [new HappyPack({id: 0})'vue', / / how many threads package at the same time, also can control the threads with ThreadPool: 4, loaders: [{/ / this is the real processing loader, the specific configuration and rules in the original agreement, the options are just copying loader:'vue-loader', options: vueLoaderConfig}]}), new HappyPack({id:'js',
    threads: 3,
    loaders: [{
        loader:'bable-loader',}})... ] ;Copy the code

With the configuration above, we can use Happypack to pack happily.

More advanced configurations can be found in the Happypack documentation

In addition, want to understand the principle of Happypack can see taobao team this article: Happypack principle analysis

4. Upgrade the packaging tool

Guiding ideology: Shotgun for cannon, upgrade packaging tools.

  1. To upgrade the node
  2. Webpack 4 is faster than 3, and 3 is faster than 2. It is recommended that Webpack be upgraded to at least 3.
  3. Upgrading various Loaders

Most of the time, the gods have helped us optimize the bottom layer, we don’t need to do any configuration, we just need to upgrade tools, of course, while upgrading to ensure the robustness of the project.

The last

A picture is worth a thousand words, and this is the optimized packaging time:

The packaging time is reduced from 120s to 34s, and the optimization rate is more than 70%. No longer need to go to the bathroom every time NPM run…

Reference article: Using WebPack to customize the front-end development environment WebPack optimization solution