Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Summary of optimization methods of webpack

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "summary of the optimization methods of webpack". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

1. Preparation: speed measurement and analysis of bundle

Since we want to optimize webpack packaging, be sure to analyze our bundle file in advance, analyze the size of each module, and analyze the packaging time is mainly where, here we mainly need to use two webpack plug-ins, speed-measure-webpack-plugin and webpack-bundle-analyzer, the former is used to measure speed, the latter is used to analyze bundle files.

Specific configuration const SpeedMeasurePlugin = require ("speed-measure-webpack-plugin"); const BundleAnalyzerPlugin = require ('webpack-bundle-analyzer'). BundleAnalyzerPluginconst smp = new SpeedMeasurePlugin ({outputFormat: "human",}) Module.exports = {configureWebpack: smp.wrap ({plugins: [new webpack.ProvidePlugin ({$: "zepto", Zepto: "zepto",}), new BundleAnalyzerPlugin (),], optimization: {splitChunks: {cacheGroups: {echarts: {name: "chunk-echarts" Test: / [\\ /] node_ modules [\\ /] chunks: "all", priority: 10, reuseExistingChunk: true, enforce: true,}, demo: {name: "chunk-demo" Test: / [\\ /] views [\\ /] demotion [\\ /] /, chunks: "all", priority: 20, reuseExistingChunk: true, enforce: true,}, page: {name: "chunk-page", test: / [\ /] src [\\ /] / Chunks: "all", priority: 10, reuseExistingChunk: true, enforce: true,}, vendors: {name: "chunk-vendors", test: / [\ /] node_ modules [\ /] /, chunks: "all", priority: 5, reuseExistingChunk: true Enforce: true,})}

Because it is based on vue-cli scaffolding, so in fact, vue-cli has helped you do some optimization work, you can see, the original project's initial configuration settings splitchunk, code segmentation, which is necessary in large projects, after all, you do not want your users to block loading a 5MB size JS file, so do code segmentation and lazy loading is very necessary.

Too far, let's take a look at this configuration. You need to repackage the configuration with smp, because SpeedMeasurePlugin will wrap a layer of proxies for your other Plugin objects in order to know when the plugin starts and ends.

Second, BundleAnalyzerPlugin is just like a normal plugin by loading the back of the plugins array.

Next, let's take a look at the initial packaging time and package content analysis:

You can see the three larger packages in the project, two of which are our third-party dependencies, three.js, lottie, lodash, echarts, and so on.

2. Begin to optimize step by step 2.1 to narrow the scope of file search and processing

This is a routine operation in webpack optimization, which basically optimizes modules and file lookups, as well as reduces loader's handling of some unnecessary modules, but the loader in vue-cli is not exposed to us, so its built-in loader processing cannot be optimized by us, but in fact, the configuration items in vue-cli have optimized the search path of loader, if your project also uses vue-cli You can see what your existing configuration file looks like from the following command line:

Npx vue-cli-service inspect > output.js

You can refer to the vuecli official documents for details.

Resolve: {modules: [path.resolve (_ _ dirname, 'node_modules')], alias: {' three':path.resolve (_ dirname,'. / node_modules/three/build/three.min.js'), 'zepto$':path.resolve (_ _ dirname,'. / node_modules/zepto/dist/zepto.min.js'), 'swiper$':path.resolve (_ _ dirname) '. / node_modules/swiper/dist/js/swiper.min.js'),' lottie-web$':path.resolve (_ dirname,'. / node_modules/lottie-web/build/player/lottie.min.js'), 'lodash$':path.resolve (_ dirname,'. / node_modules/lodash/lodash.min.js'),}}, module: {noParse:/ ^ (vue | vue-router | vuex | vuex-router-sync | three | zepto | swiper | lottie-web | lodash) $/}

Specify the path to find third-party modules through modules.

Specify a third-party module through alias to find the packaged compressed js file directly.

Specify noparse through module and no longer analyze dependencies on third-party modules.

Optimization effect: 2s?

You can see that the time is reduced by two or three seconds, fluctuating in 30s, and it doesn't feel much different.

2.2 try using happypack

Since I read a lot of articles about webpack optimization before webapck optimization, I would also like to try to use happypack to optimize packaging time.

Before you want to package in happypack, there are probably two ways to say:

1. Multithreaded packaging is already used by default in webpack4, so the effect of happypack packaging is not obvious.

2. Vue does not support happypack packaging, so you need to set thread-loader.

But the author thought about it for a while, or give it a try, at the worst, I only set happypack for JS and CSS files.

But here comes the problem again. Vue-cli encapsulates loader in it. How can I get its configuration and rewrite its loader configuration at this time?

By flipping through the official documentation of vue-cli, we can see the following usage instructions:

ConfigureWebpackType: Object | Function if this value is an object, it will be merged into the final configuration through webpack-merge. If this value is a function, the parsed configuration is received as a parameter. This function and can modify the configuration and return nothing, but also return a cloned or merged version of the configuration.

To this end, the author specially debugged into the vue-cli source code to find out:

Process description:

Because we execute the command line vue-cli-service build, in fact, we first go to the .bin folder of node_modules to find the corresponding executable file, and the vue-cli-service under .bin will map to the execution file in the corresponding third-party library.

So we can find the address of this executable file:

/ node_modules/@vue/cli-service/bin/vue-cli-service.js

Found the entrance, and then we want to enter the debugging of nodejs. In previous development, we would start a background service through node-inspect app.js, and then enter the debugging interface in Google browser (F12 select the small green button)

But there are difficulties here, because our packaging build is executed at once, unlike a background service, it is monitored in real time, and the service is started all the time. After looking up, if you want to debug an ordinary nodejs file, you need to do it in this way:

Node-inspect-brk=9229 app.js

So, in order to force your way into the vue-cli source code for debugging, you can see the processing flow of vue-cli. You need to enter the following command line:

Node-inspect-brk=9229 node_modules/@vue/cli-service/bin/vue-cli-service.js build

The command line above is equivalent to vue-cli-service build.

In this way, we finally walked into the source code of vue-cli and looked at its execution flow. You can make a breakpoint in the corresponding location and view the variable data in the scope at this time.

You can see this operation in the vue-cli source code, and the function we passed in will be executed to determine whether the function has a return value to determine whether to merge into its internally configured config.

From this code, we can see that if we configure configWepack as a function, and then get the config configuration item in the form of parameters, it is an object itself, and the object is in the form of reserved references, so if we modify the incoming config object directly, we can achieve our original goal! Modify the built-in loader of vue-cli!

Of course, in addition to the breakpoint inside to see the configuration, as I just said, we can use the command line output to an output file to view the existing configuration.

Here you can take a screenshot to see the internal configuration of vue-cli:

It may be a bit of nonsense, but through the breakpoint, we can see that vue-cli has actually set exclude on the js file, and also set up cache-loader for us, which means that webpack is one of the usual optimization methods, and using cache-loader cache also does it for us.

Going back to the starting point, we wanted to deal with loader for JS and CSS, so imitating most configurations, I made the following changes:

ConfigureWebpack: (config) = > {console.log ("webpack config start"); let originCssRuleLoader = config.module.rules [6] .oneOf [0] .use; let newCssRuleLoader = 'happypack/loader?id=css' Config.module.rules [6] .oneof [0] .use = newCssRuleLoader config.module.rules [6] .oneOf [1] .use = newCssRuleLoader config.module.rules [6] .oneOf [2] .use = newCssRuleLoader config.module.rules [6] .oneOf [3] .use = newCssRuleLoader. / / other code}

Try to modify the loader configuration of css. Then configure plugins as follows:

Plugins: [new HappyPack ({id: 'css', threads: 4, loaders: originCssRuleLoader}),]

I thought it would be OK, but I'm sorry to tell you that I made a mistake.

You can see that the error message is that there was an error when processing the vue file.

How to solve

The author Baidu, but also Google, probably said that happypack does not support vue-loader, at the same time, according to the error also checked to deal with the plan, by setting parallel parameters, or invalid.

The author even suspected that my own happypack configuration was wrong, so I migrated the configuration as is to another non-vue project, and everything worked fine.

Answer: there is no solution to this question.

Cause analysis:

Because the vue file will contain CSS, vue-loader will extract the css and give it to other loader for processing. Vue-loader-plugin will tell other loader by adding a query string to the vue file that it needs to be processed. What does it mean? Our vue-loader notifies other loader processing when processing files, but at this time we have rewritten the loader configuration to happypack, and vue is not compatible with happypack, resulting in an error. I'm sorry to tell you that vue-cli failed to connect to happypack--.

(note: this part is mainly the author's exploration in the process of webpack optimization. Although we can't make our webpack package optimize well in the end, we can also learn a lot in the process of exploration, including vue-cli 's handling of configuration objects. How to debug normal file nodejs code? How to deal with vue files in vue-loader? What did vue-loader-plugin do for us? And these are to slowly read their own, slowly step on the pit to understand ~)

2.3 use dllplugin

Like most webpack optimization tutorials, the author also tried to use dllplugin for optimization, the essence of the plug-in is to extract our commonly used third-party modules, separately packed into a file package, and then inserted into our html page, so that every time we package, we do not need to deal with third-party modules, after all, third-party modules often thousands of lines.

Process description:

1. Configure webpack.dll.js to package for third-party libraries

2. Configure plugin in vue.config.js

3. Introduce the js file packaged by dll into html. (deployment of CDN is generally adopted)

Since there are many large third-party libraries in the project, such as three, echart, etc., the author has configured the following: (webpack.dll.js)

Const webpack = require ("webpack") const path = require ("path") const HtmlWebpackPlugin = require ('html-webpack-plugin') Module.exports = {entry: {vuebundle: ['vue',' vue-router', 'vuex',], utils: [' lodash', 'swiper',' lottie-web', 'three',] Echarts: ['echarts/lib/echarts', "echarts/lib/chart/bar", "echarts/lib/chart/line", "echarts/lib/component/tooltip", "echarts/lib/component/title", "echarts/lib/component/legend",]}, output: {path: path.resolve (_ _ dirname) '. / static/'), filename:' [name] .dll.js', library:'[name] _ library'}, plugins: [new webpack.DllPlugin ({path: path.join (_ _ dirname, 'build',' [name]-manifest.json'), name:'[name] _ library'})]}

According to the size of different libraries, packed three packages, why not pack into one package? A package is too big, and you don't want your users to load a large JS package and block it, affecting page performance.

Next is the configuration of vue.config.js:

Plugins: [new webpack.ProvidePlugin ({$: "zepto", Zepto: "zepto",}), new DllReferencePlugin ({manifest: require ('. / build/echarts-manifest.json'),}), new DllReferencePlugin ({manifest: require ('. / build/utils-manifest.json'),}) New DllReferencePlugin ({manifest: require ('. / build/vuebundle-manifest.json'),}), new BundleAnalyzerPlugin (),]

DllPlugin is introduced. Next, configure HTML:

(since the author did not upload the js file packaged by DLL to CDN, I had to set up a local node server to return static resources.)

Then npm run serve, start page debugging and development ~

Comfortable ~

Optimization results:

Due to the lack of large third-party libraries, the time is controlled at about 20s. The optimization is relatively obvious.

3. Summary of optimization and exploration

When the optimization comes to this, it's almost over.

The common optimization methods of webpack, such as optimizing path lookup, setting cache, happypack and dllplugin, the first two vue-cli have already done some for us, but happypack cannot be accessed because it is not compatible with vue. Dllplugin has achieved obvious optimization by extracting third-party libraries separately.

Of course, the author also tried to eliminate some useless code in the project, but it was also innocuous.

Summary of webpack optimization methods:

1. Find the path of the optimization module

2. Eliminate unnecessary and useless modules

3. Set cache: cache the execution result of loader (cacheDirectory/cache-loader)

4. Set multithreading: HappyPack/thread-loader

5. Dllplugin extracts the third-party library

Of course, this is for development optimization, but what if it is for deployment optimization? We can set up splitchunk, load on demand, deploy CDN, and so on, so we won't expand here.

This is the end of the summary of the optimization methods of webpack. Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report