Webpack Performance Optimization __web

Source: Internet
Author: User
Tags browser cache
a few words of nagging

The use of Webpack also has a period of time, from Webpack1 to Webpack3, there are too many twists and turns and entanglements. Webpack is undoubtedly powerful, powerful to no friends, Webpack design is also great, it can compile our code, with various loader, so that we can use a variety of ES6/ES7 characteristics, can use sass/less, can write react code and so on.

Webpack has many of our familiar features, such as Webpack-dev-server, hot Module replacement, Sourcemap, Uglifyjsplugin, automatically generate HTML, and so on, everything is configured, So many configuration items also bring the problem of poor and readable configuration files, and the most intolerable is the Webpack packaging performance problem.

Recently contacted a project, this engineering module has more than 100, in the full volume build, will report the memory overflow, package failure. Even if the module is not too much of the project, will find the packaging speed is very slow problem, from then on can be justified in the process of building to a toilet, drink a glass of water or something.

Based on the performance of this pain point, and then began to toss, want to do some improvement to build performance.

tossing the road

Version upgrade

With the upgrade of the Webpack version, Webpack's configuration entry began to be limited, and the Webpack configuration entry after version 2.0 has not allowed custom attributes, and the core revolves around entry, output, loaders, and plugins. This is to some extent making webpack configuration files look less messy.

Webpack official also noted the performance problem, so after the 2.0 version, many of the webpack1 need to configure some of the performance of the Plug-ins are also the default to open, such as occurrenceorderplugin (sorted output), Dedupeplugin ( Delete duplicate data) and so on, loaders will also open the cache by default.

After 2.0 version from the optimized configuration, to the ES6 module,promise and other standards, and then to the compilation environment and performance optimization, and then to the overall standardization of API design, relative to the 1.0 version of the improvement is very significant.

The 3.0 version of Webpack adds scope enhancements, and older versions webpack need to wrap each module in a separate function closure to implement the modular system. These wrapper functions tend to degrade the performance of JavaScript code running in browsers. In Webpack3, Plug-ins are provided to allow developers to enable the scope Elevation feature to avoid this additional loss of performance:

...
Plugins: [
    new Webpack.optimize.ModuleConcatenationPlugin ()
]
...

The scope elevation feature can remove the encapsulation function of the module, so the volume of the code will be reduced after the plug-in is introduced. So upgrading Webpack is the key to improving performance.

Reduce Reliance

Webpack is the ability to package all of the static resources into a bundle and compile the code through a variety of loader, so if there are too many modules to rely on, this can definitely lead to performance degradation. So we should try to reduce dependencies and remove those that are not used.

Modules and Dependent locations

By setting the Resolve property of the Webpack, specifying the extension of the loaded file and the location of the Configuration Module library (node_modules), specifying the path alias by configuring alias, the path to use the alias in your code may elevate the file lookup speed. You can also specify file paths and exclude file paths during the Webpack configuration loader. This is to a certain extent make file lookup quickly.

...
Resolve: {
    extensions: ['. js '],
    alias: {
      globalLib:path.join (__dirname, './src/lib ')
    },
    Modules: [Path.resolve (__dirname, ' node_modules ')],
},
...
Module: {
    rules: [
        ...
        ] {
         test:/\.js?$/,
         exclude:/node_modules/,
         include:path.resolve (__dirname, ' src '), use
         : [
           {
             loader: ' Happypack/loader ',
             options: {
               id: ' JS ',
             },
           },
         ],
       },
        ...
    ]
} ,
...

Separate configuration of the development environment and the online environment

The development environment and the code requirements of the online environment are inconsistent, the development environment is more stringent, but in the development environment does not need to do so, some plug-ins are very consuming performance, then in the development environment we do not need to reference, such as Optimize-css-assets-webpack-plugin , Uglifyjsplugin, Assets-webpack-plugin, Dllreferenceplugin, etc., these code optimization compression level of plug-ins online environment more important, then the development environment can not be loaded. We can make judgments in the configuration file by defining the environment variable node_env=production.

...
Const NODE_ENV = Process.env.NODE_ENV;
if (node_env = = ' production ') {
    config.plugins.push (
        new Webpack.optimize.UglifyJsPlugin ({
          compress: {
            ) Unused:true,
            dead_code:true,
            warnings:false,
          },
          Sourcemap:false,
          parallel: {
            cache: True,
            Workers:os.cpus (). length,
          },
          minimize:true,
          mangle: {
            except: [' $ ', ' exports ', ' Require '],
          },
          output: {
            ascii_only:true,},},
    )
}
...

Packaging DLLs

By using the Dllplugin & Dllreferenceplugin component, we can individually package and reference some common libraries so that they do not need to be recompiled in the process of building other code. Dllplugin produces vendor.js/vendor.css and manifest.json,vendor.js/ Vendor.css stored in a packaged library file, vendor.js in the global a function similar to the Require function, while the Manifest.json store the dependent resource path and ID, provided to dllreferenceplugin use, DLLREFERENCEPL Ugin in the processing of files, encountered in Manifest.json resources, using vendor.js burst to the global approach to deal with, and will not be packaged in the file.

Webpack.dll.js ...
Const VENDORS = [
  ' react ',
];
...
Module.exports = {
  output: {
    path:path.resolve (' Build '),
    filename: ' [name].js ',
    library: ' [name] ',
  },
  entry: {
    vendor:vendors,
  },
  ...
  Plugins: [
    ...
    ] New Webpack. Dllplugin ({
      path: ' Manifest.json ',
      name: ' [Name] ', context
      : __dirname,
     })
     ...
  ]
  ...
};

Webpack.config.js ...
Plugins: [
 ...
  ] New Webpack. Dllreferenceplugin ({context
    : __dirname,
    manifest:require ('./manifest.json '),
    name: ' Vendor ',
  })
  ...
],
...

Using Happypack

Happypack can configure compilation caching and make full use of multiple processes to compile static resources, which greatly increases the speed at which code is built. Here recommend an article Happypack principle analysis

@file webpack.config.js
exports.plugins = [
  new Happypack ({
    id: ' JSX ',
    threads:4,
    loaders: [] Babel-loader ']
  },

  new Happypack ({
    id: ' coffeescripts ',
    threads:2,
    loaders: [' Coffee-loader ']
  })
];

Exports.module.loaders = [
  {
    test:/\.js$/,
    loaders: [' Happypack/loader?id=jsx ']
  },

  {
    test:/\.coffee$/,
    loaders: [' happypack/loader?id=coffeescripts ']
  },
]

Leveraging caching

Full use of a variety of cacheable configuration, the above happypack can be cached, uglifyjsplugin can be cached, each loader can configure caching and so on.

...
Const OS = require (' OS ');
Const HAPPYPACK = require (' Happypack ');
...
Const CREATEHAPPYPLUGIN = function (ID, loaders) {return
  new Happypack ({
    ID,
    loaders,
    threadPool: Happypack.threadpool ({Size:os.cpus (). length}),
    cache:true,
    verbose:true,
    debug:true,
  });
...
Plugins: [
    ...
    ] Createhappyplugin (' JS ', [' babel-loader?cachedirectory ']) ...
    New Webpack.optimize.UglifyJsPlugin ({
      compress: {
        unused:true,
        dead_code:true,
        warnings: False,
      },
      Sourcemap:false,
      parallel: {
        cache:true,
        workers:os.cpus (). length,
      },
      minimize:true,
      mangle: {
        except: [' $ ', ' exports ', ' require '],
      },
      output: {
        ascii_ Only:true,
      },
    })
]

Extracting common code

Using the Commonschunkplugin plug-in, you can extract the common code referenced in the resource, and then we can make a separate reference in the page. Allows the tool code and business code to be separated. Plus the browser's ability to cache files, can also improve the speed of online page loading.

...
Plugins: [
    ...
    ] Extract the common code for all the entry files, generate Common.js
    new Webpack.optimize.CommonsChunkPlugin (' Common.js '),
    ...

Code segmentation

By using require.ensure () to load the code on demand, Webpack collects the dependencies in the ensure, packs them into a separate file, loads them asynchronously in the form of a JSONP, and makes code splitting and loading on demand in this way, There is no small help to improve the performance of the page, but this method needs to modify the code, not very suitable for old engineering transformation.

CSS Segmentation

Using Extract-text-webpack-plugin to extract CSS files, separate references, this can reduce the size of the bundle, the other CSS file needs to be loaded onto the DOM elements, that is, in the header, anyway, it is wise to do so.

Fast-sass-loader

This is a high-performance sass loader, in a relatively large sass project, the speed is 5-10 times the sass-loader.

Hash value

By configuring the hash value, using each file content to calculate the MD5 as the file version number, can greatly use the browser cache, improve page performance, through Assets-webpack-plugin this plug-in, you can generate a hash value JSON file, convenient for us to configure. The following introduction of these, in fact, from the page load performance to consider the problem, here is also proposed.

Enemy

Analysis of Webpack Construction

If we are not very satisfied with the speed of webpack construction, we can use the Webpack-analyse or Webpack-visualizer tools to analyze the construction process, in order to further optimize, do the enemy win, Before we start, we need to use the following command as a JSON file for the build process:

The next process is visualization, we upload the JSON file, and then we see the build results.

Just talk .

Through the above optimization, the speed of webpack construction is not a small improvement. After the project was completed, the packaging time before and after the transformation was compared, the speed increased more than 10 times times. But I think this is not the ultimate solution, the result is not my satisfaction. Believe that the subsequent Webpack version, can let us have a simple configuration, build efficient, powerful tool. There are mistakes in the article, please point out, learn from each other and progress together. Best regards!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.