preface

This is my third article about getting started

Bite the bullet and you’ll find some things aren’t that hard. Here, from a personal point of view, summarizes several requirements encountered on the project, packaging optimization.

Requirement 1 ———— package compression

The story begins like this. We upgraded the front-end package, the local nginx agent is no problem, but in a nuclear site, after logging in to the content is not the home page. The js request of the on-site response interface failed, but THERE was no mistake in my hard bar packaging files, and no such problem occurred in other projects. Maybe there is no way, they put out the file before the upgrade, said that we upgrade after the packaging of a single file is too large, can be caused by this reason. Even when FACED with this challenge, I have no idea how to reduce the size of the packaged individual files. The CompressionPlugin came into my sight.

Package files before use

Package and compress CSS, JS, and HTML files that exceed 10K. The following code

//vue.config.js
const CompressionPlugin = require("compression-webpack-plugin");
configureWebpack: config= > {
    if (process.env.NODE_ENV === "production") {
      return {
        plugins: [
          new CompressionPlugin({
            test: /\.js$|\.html$|.\css/.// Match the file name
            threshold: 10240.// Compress data over 10K
            deleteOriginalAssets: false // Do not delete the source file})]}; }},Copy the code

Package files after use

By comparison, large files are generated corresponding compressed GZ files, we then through the Nginx proxy, let the browser request corresponding gz files, the corresponding file volume immediately down. In this way, I compressed the volume of the file down, thinking, this will be a nuclear site to say nothing. Eventually the problem was resolved, not because of volume, but because of network limitations, a dependency load failed. The process is very intoxicating, I won’t go into details here.

Requirement 2 ———— Remove the comment code

One day, the manager found me again. He said, bao ah, let’s package the notes of the document and find a way to remove them. Because of national network security, certain project has strict standards for some sensitive fields. I said, “Okay, just give me some time.” Nonsense not to say, do not understand the degree, is our ‘Baidu people’ the best quality. Here it is, uglifyjs-webpack-plugin.

Before removing comments

Remove the comment

configureWebpack: config= > {
    if (process.env.NODE_ENV === "production") {
      return {
          new UglifyJsPlugin({
            uglifyOptions: {
              mangle: false.output: {
                  beautify: true,},}})]}; }},Copy the code

After removing the comments, there is a lot of code here, and you can see that there is no obvious comment segmentation on the right side, which is a great effect.

Requirement 3 ———— Remove web preloading

This requirement is kind of self-imposed. Once, I was curious about the packaged file, and I wondered what would be in the packaged HTML?

If you look closely, you’ll notice that your HTML has a lot of reference files that you didn’t write in the actual HTML interface. So what are these? Can I get rid of it? If you look more closely, you’ll find the keywords prefetch and preload. After some searching, I found this explanation:

Prefetch: Used to mark content preloaded by the browser during idle time after the page has been loaded. By default, the Vue CLI app automatically generates prefetch prompts for all JavaScript files generated as Async Chunks (the product of on-demand code splitting via dynamic import()).

Preload: Marks resources to be used after the page loads. The browser loads the Preload tag file before the body renders. The Vue CLI application automatically generates preload prompts for all files required for initial rendering

Our browser will preload some resource files that we need, and if we don’t do that, the loading speed of the entire browser will slow down. At this point, we need to tell the browser, don’t do what I didn’t give you permission to do!

 chainWebpack: config= > {
   entryConfig.pagelists.forEach(page= > {
      config.plugins.delete(`preload-${page}`);
      config.plugins.delete(`prefetch-${page}`);
    });
 }

Copy the code

Optimization 4 ———— Stripping package dependency analysis

This is also my favorite point, I hope that each front-end person can do a volume analysis of their packaged files. Without further ado, first the code:

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;


 chainWebpack: config= > {
   config.plugin('webpack-bundle-analyzer').use(BundleAnalyzerPlugin);
 }


Copy the code

With this plug-in dependency, you will see this interface every time you run your project

What are we gonna do with this? Here, I’ll use Element-UI as an example. From the figure above, we can see that The Element-UI occupies a large area on the diagram, which means that the package is very large. By modularity, at this point, we must be thinking, well, can we put these large files in a separate package? Not with all the node_modules. The answer is definitely yes.

Here you need to know about splitChunks. Because all third-party libraries introduced are, by default, packaged into the Vendors module, the more they are introduced, the bigger the files, and the worse the performance. SplitChunks, on the other hand, segmented the VENDORS module and reduced the size of the vendors files. I’ve added a lot of comments here that I hope will help you. The specific code is as follows,


 chainWebpack: config= > {
   config.optimization.splitChunks({
     //chunks————> Decide which modules to extract
      Async: import(' XXX ') or require([' XXX '],() =>{})
      // Initial, initial; // Initial, initial; // Initial;
      //all, both asynchronously and synchronously loaded modules are extracted and packaged into a file
      chunks:"initial".//minSize————> Extract the minimum value of the module
      // The default value is 30000. The size of the module before compression exceeds this size
      minSize:30000.//maxSize————> Extract the maximum number of files
      //0 is the default value. If the file size exceeds the maximum value, the file will be split
      maxSize:0.// Do not limit the size
      //minChunks————> Minimum extraction times
      // The minimum number of times the module to be extracted is introduced
      minChunks:2.//maxAsyncRequests————> Maximum number of asynchronous quests (default: 6)
      maxAsyncRequests:6.//maxInitialRequests————> The number of js files that can be loaded at the same time (including entry files)
      maxInitialRequests:4.// Priorities: maxInitialRequests/maxAsyncRequests 

      //automaticNameDelimiter————> Package the separator of the generated JS file name
      / / automaticNameDelimiter: "~", / / the default
      //name————> The name of the js file generated by packaging

      /* * === = cacheGroups === * Configures a scheme for extracting modules. Except for the following special options, all other options are consistent with the outside, some of them are their own, no external configuration * * test. Matches the resource path or name of the module to extract. Values are regular or functions. * * priority. Priority of the scheme. A larger value indicates that the scheme is preferred when extracting modules. The default value is 0 * * reuseExistingChunk. True/false. When true, if the current module to be extracted already exists in the generated JS file generated by packaging, the module will be reused instead of packaging the current module to be extracted to generate a new JS file. * * enforce. True/false. If true, ignore minSize, minChunks, maxAsyncRequests, and maxInitialRequests
      cacheGroups: {common: {
          // Extract the public chunk required by all entry pages
          name: "chunk-common".chunks: "initial".minChunks: 2.maxInitialRequests: 5.minSize: 0.priority: 1.reuseExistingChunk: true.enforce: true
        },
        vendors: {
          name: `chunk-vendors`.test: /[\\/]node_modules[\\/]/,
          priority: -10.chunks: 'initial'
        },
        icons: {minChunks:1.name:"chunk-icons".priority:4.test:/[\\/]src[\\/]style[\\/]font/
        },
        vueUI: {
          name: `vueUI`.test: /[\\/]node_modules[\\/]vue[\\/]/,
          priority: 4.chunks: 'all'.reuseExistingChunk: true.enforce: true
        },
        element: {
          name: "elementUI".test: /[\\/]node_modules[\\/]element-ui[\\/]/,
          chunks: "all".priority: 3.reuseExistingChunk: true.enforce: true}}})}Copy the code

After configuration, let’s look at the volume ratio after packaging

By comparison, our element-UI generates its own separate file. Here you can also look at the vUE alone generated comparison, the code I’ve put up.

In general, these points can be used in our packaging configuration on scaffolding to optimize our packaged files. Of course, there are many points that I haven’t touched on yet, I hope we can share and improve together, learn from each other, and I hope my sharing can help you, thank you.