1, vueCli to check the size of the packaged file ratio

⚠ ️ vue – cli2 use webpack – bundle – analyzer

// The NPM run build --report command is already integrated into a project built with vue-cli2

⚠️ The following applies to: Vue-Cli3

1.1 Installation Dependencies

$ npm install webpack-bundle-analyzer --save-dev

1.2 configuration vue. Config. Js

chainWebpack: Config.plugin ('webpack-bundle-analyzer') {// Config => {// Config. Plugin ('webpack-bundle-analyzer') .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin,[ { analyzerMode: 'server' } ]) } /** analyzerMode? : 'server' | 'static' | 'json' | 'disabled'; * Can be "server", "static" or "disabled". * Defaults to "server". * In "server" mode analyzer will start HTTP server to show bundle report. * In "static" mode single HTML file with bundle report will be generated. * In "json" mode single JSON file with  bundle report will be generated * In "disabled" mode you can use this plugin to just generate Webpack Stats JSON file by setting "generateStatsFile" to true. */

The package script is configured in the scripts of package.json

$ "build": "vue-cli-service build --report"

Execute the command:

$ npm run build

Open your browser: http://127.0.0.1:8888 and you will see a “visual” file percentage

❗ Extension: If an endpoint sends a warning: (asset size limit of 244KiB May affect network performance). ! [[picture uploaded…(20200428150718890. PNG-E3528-1624502443756-0)] (https://upload-images.jianshu…

🧠 solution: Configure in vue.config.js

Module. exports = {// Webpack configureWebpack: {// Exports = {module.exports = {// Webpack {Hints :' Warning ', Hints :' Warning ', Hints :' Warning ', Hints :' Warning ', Hints :' Warning ', Hints :' Warning ', Hints :' Warning ', Hints :' Warning ', Hints :' Warning ' MaxAssetSize: maxAssetSize: maxAssetSize: maxAssetSize: 30000000 function(assetFilename) { return assetFilename.endsWith('.js'); } } }, // vue.config.js // configureWebpack: config => { // config.performance = { // hints: 'warning', // maxEntrypointSize: 50000000, // maxAssetSize: 30000000, // assetFilter: function(assetFilename) { // return assetFilename.endsWith('.js'); //} //} //}

For more details, see Webpack Chinese documentation – Performance.

2. Remove Console

If you are using Webpack V5 or above, you do not need to install this plugin. Webpack V5 comes with the latest terser-webpack-plugin. If you are using Webpack V4, you must install a version of terser-webpack-plugin V4.

2.1 Installation Dependencies

$ npm install terser-webpack-plugin -D

2.2 configuration vue. Config. Js

const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
    chainWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
          config.optimization.minimizer([
            new TerserPlugin({
              test: /\.js(\?.*)?$/i,
              terserOptions: {
                compress: {
                  drop_console: true,
                  pure_funcs: ['console.log']
                }
              }
            })
          ])
        } else {
          // disable optimization during tests to speed things up
          config.optimization.minimize(false)
        }
      }
}

For more details, please refer to the Webpack Chinese documentation -TerserWebpackPlugin

❓ pass if error:

Error: optimization.minimizer() no longer supports being passed an array. Either switch to the new syntax (https://github.com/neutrinojs/webpack-chain#config-optimization-minimizers-adding) or downgrade to webpack-chain 4. If using Vue this likely means a Vue plugin has not yet been updated to support Vue CLI 4+.

🧠 is reconfigurable

if (process.env.NODE_ENV === 'production') { config.optimization.minimizer('js') .use(require.resolve('terser-webpack-plugin'), [{terserOptions: {Comments: true, compress: {drop_console: true, drop_debugger: true // pure_funcs: ["console.log"] } } }]) } else { // disable optimization during tests to speed things up config.optimization.minimize(false) }

❗ post extension: Why remove the production console?

Console. log: Prints a message to the Web development console, often used for debugging analysis at development time. Sometimes during development, you need to print some object information, but forget to remove the console.log statement when you publish it, which can cause memory leaks.

Objects passed to console.log cannot be garbage collected ♻️ because the object information needs to be viewed in the development tool after the code is run. So it is best not to console. Log any objects in production.



Example code:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Initial-scale =1.0"> <meta http-equiv=" x-ua-compatible "content="ie=edge"> <title>Leaker</ head> <body> <input type="button" value="click"> <script> ! function () { function Leaker() { this.init(); }; Leaker.prototype = { init: function () { this.name = '*'.repeat(1e5); console.log("Leaking an object %o: %o", (new Date()), this); // This object cannot be recycled}}; document.querySelector('input').addEventListener('click', function () { new Leaker(); }, false); }() </script> </body> </html>

Here are some steps to analyze Chrome’s DevTools — >Performance:

  1. Enables the record for Performance
  2. Execute the CG button to create a baseline guide
  3. Click the [Click] button several times to create a new Leaker object
  4. Execute CG button
  5. Stop recording



It can be seen that[JS Heap]The line does not end up falling back to the base reference, so there is clearly memory that is not being reclaimed. If I change the code to

// console.log("Leaking an object %o: %o", (new Date()), this);



Repeat the above operation steps, and the analysis results are as follows:

As you can see from the comparative analysis, objects printed by console.log will not be collected by the garbage collector. Therefore, it is best not to console. Log any objects in the page, including WARN, ERROR, etc. This can affect the overall performance of the page, especially in a production environment, where these details require special attention.

Third, compress the picture

3.1 Installation Dependency

$ npm install terser-webpack-plugin -D

3.2 configuration vue. Config. Js

config.module .rule('images') .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/) .use('image-webpack-loader') .loader('image-webpack-loader') .options({ bypassOnDebug: true, disable: process.env.NODE_ENV ! == 'production' });

IV. UI library is loaded on demand

For most systems, there are some UI component libraries, such as Ant Design or Element UI. These components can be imported on demand. When using these components, if we only use some of them, we can configure loading on demand and modify the code in main.js:

import { Pagination, Icon, Tabs, } from 'ant-design-vue' // import 'ant-design-vue/dist/antd.css' = 'Babel'; use(Pagination).use(Icon); .use(Tabs)

Then modify babel.config.js as follows:

"plugins": [ ["import", { "libraryName": "ant-design-vue", "libraryDirectory": "es", "style": "css" }], // `style: True 'will load less files]

In this way, the JS and CSS files corresponding to the component can be loaded on demand.

Five, routing lazy loading

For large B-side management system projects, Vue Router is basically used to manage routing. These projects involve a large number of pages. Therefore, in order to prevent the first screen resource from being too large, routing lazy loading resource, namely Code Splitting, should be adopted to separate the resources of each page. This is simply configured in router.js:

$component: () => import('./index.vue'); $component: () => import('./index.vue');

6. Moment optimization

6.1 Problem Description

According to the packaging analysis diagram, other language packages of Moment under Locale mainly occupy a larger volume. The default language package is en, so you can simply ignore unpackaged files in locale without the need for other languages.

Ignore before:

After Ignore:

6.2 The solution uses Webpack’s built-in IgnoReplugin plug-in

// vue.config.js var webpack = require('webpack') module.exports = { // ... ChainWebpack: config => {config.plugin('ignore').use(new webpack.ignoReplugin (/^.\/locale$/, /moment$/)); // ignore all files under /moment/locale} //... Here omit other configuration}

At Webpack build time, if the path of an incoming file matches /^./locale$/, the file will be ignored and will not be packaged.

  • /^./locale$/ is not an exact match. Only the aliasedRequire(‘./locale/’ + name) is locale related, but does not match the regular. Moment’s SRC source file contains import… The from ‘. / locale. But in the moment package.json where main refers to a compiled file and not to a SRC file, that’s a bit of a funny thing, so Debug IgnoReplugin takes a look at it.

  • Is the request in the picture really./locale, blind or Webpack’s problem? “AliasedRequire (‘./locale/’ + name)” is in fact aliasedRequire(‘./locale/’ + name).

  • When Webpack compiles an expression such as require(‘./locale/’ + name), Webpack looks for files under the directory ‘./locale/’ that match the regular expression /^.*.$/. Because the name is unknown at compile time, Webpack introduces each file into the bundle as a module, which is why the compiled file is so large after the moment is introduced.

6.4 What if I need to set a locale after adding ignoReReugin?

  1. After adding webpack.ignoReplugin, the file size is reduced, but after setting Moment.locale (‘zh-cn’), the date after format is still in English, and the language has not been switched.

Before adding: Include the file size of momen.js after packaging



After Added: Include the file size of momen.js when packaged

  1. Loss of functionality is certainly not acceptable, what to do? How to do?
  2. A solution is also provided on the Moment documentation, the Moment-Locales-Webpack-plugin

    $ npm install --save-dev moment-locales-webpack-plugin
    // vue.config.js
    new MomentLocalesPlugin({
      localesToKeep: ['zh-cn'],
    })
    
     // const MomentLocalesPlugin = require('moment-locales-webpack-plugin')
         // config.plugin('moment-locales-webpack-plugin').use(
         //     new MomentLocalesPlugin({
         //         localesToKeep: ['zh-cn']
         //     })
         // );
  3. The Moment default locale is en, which is bound to be packaged. If you need to configure other languages, you can configure it via LocalestoKeep, and other language packages that are not used will not be packaged.

Vue.config.js is configured as follows

config.plugin('moment-locales-webpack-plugin').use(
            new MomentLocalesPlugin({
                localesToKeep: ['es-us', 'ru', 'cs', 'hi', 'uk']
            })
        );

You can see that when you package it, it’s all packaged and deleted! ! Png-2486c4-1624615311186-0 png-2486c4-1624615311186-0 PNG] [https://upload-images.jianshu…

6.5 Principle Analysis of Moment-Locales-Webpack-Plugin

  1. Ignoring all language packages (except en) with IgnoReplugin if option is not configured
  2. If Option is set, use the ContextReplacementPlugin to set Webpack lookup rules at compile time to find the specified locale.

    . if (localesToKeep.length > 0) { var regExpPatterns = localesToKeep.map(function(localeName) { return localeName + '(\\.js)? '; }); return new ContextReplacementPlugin( /moment[\/\\]locale/, New RegExp (' (' + regExpPatterns. Join (' | ') + ') $') / / configuration webpack compilation phase lookup rules, specifying the language pack); } else { return new IgnorePlugin(/^\.\/locale$/, /moment$/); }...

    Webpack repeatedly packages dependencies with the same name

I recently installed the Webpack-Bundle-Analyzer plugin to analyze the package composition and found that some packages are packaged repeatedly, which can make the built packages extremely bloated. This is mainly because we often refer to a lot of third-party packages, and the libraries of many tool classes are also indirectly dependent on other packages, so it leads to the phenomenon of repeated packaging, such as bn. Js in the figure below.

Add the following configuration under the resolve in Webpack:

// exports = {alias:{'bn. Js ': path.resolve(process.cwd(), 'node_modules', 'bn. Js ')}}; // exports = {configureWebpack:{alias:{'bn. Js ': path.resolve(process.cwd(), 'node_modules', 'bn.js') } } } }; // The third method const path = require('path'); Function resolve(dir){return path.join(__dirname,dir)//path.join(__dirname)} module.exports={return path.join(__dirname,dir); Set ("@", resolve(" SRC "))} if (config.resolve (" SRC ")) {

Alias is used to alias the package and to force a reference to the unified path. The result is that you will see only bn.js.

After the optimization

Before the optimization

8. Use prefetch and preload selectively

prefetch

<link rel="prefetch" ></link>

This code tells the browser that this resource will be used for a navigation or function in the future, but that the download order of this resource is relatively low weight. This means that PREFETCH is usually used to speed up the next navigation, not the current one. preload

<link rel="preload" ></link>

Preload is typically used for the key resources that this page will use, including key JS, fonts, and CSS files. Preload will increase the weight of the resource download order, making the key data download well in advance, and optimizing the page opening speed.

In projects generated using the VUE CLI, when we configure the routing lazy load, by default Webpack will prefetch and preload all lazy load resources during the build, so when you open the home page, you will see a large number of prefetch and preload requests, as shown in the figure below:

// Disallow prefetch and preload chainWebpack: Delete ('prefetch') config.delete ('preload')} // Selectable prefetch and preload config.plugin('prefetch').tap(options => { options[0].fileBlacklist = options[0].fileBlacklist || [] options[0].fileBlacklist.push(/myasyncRoute(.) +? \.js$/) return options })

The above code modifies the chainWebpack of vue.config.js to add the configuration.

Summary: Smash it out ️ Smash it out, Smash it out, Smash it out, Smash it out, Smash it out, Smash it out, Smash it out, Smash it out

Refer to the link: https://segmentfault.com/a/11… https://zhuanlan.zhihu.com/p/… https://www.jianshu.com/p/4f8… https://juejin.cn/post/684490… https://blog.csdn.net/u010352…