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

What is the asynchronous loading principle of webpack?

2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article mainly explains "what is the principle of asynchronous loading of webpack". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what is the principle of asynchronous loading of webpack".

Principle of webpack Asynchronous loading

Webpack ensure some people call it asynchronous loading, also known as code cutting, he is actually the js module to independently export a .js file, and then use this module, and then create a script object, add to the document.head object, the browser will automatically help us initiate a request, to request this js file, and then write a callback function, let the request to the js file to do some business operations.

For instance

Requirements: main.js relies on two js files: A.js is the logic executed after clicking the aBtn button, and B.js is the logic executed after clicking the bBtn button.

Webpack.config.js, let's first write the code for the configuration packaged by webpack.

Const path = require ('path') / / path processing module const HtmlWebpackPlugin = require (' html-webpack-plugin') const {CleanWebpackPlugin} = require ('clean-webpack-plugin') / / introduce CleanWebpackPlugin plug-in module.exports = {entry: {index: path.join (_ _ dirname,' / src/main.js'),}, output: {path: path.join (_ _ dirname,'/ dist') Filename: 'index.js',}, plugins: [new HtmlWebpackPlugin ({template: path.join (_ _ dirname,' / index.html'),}), new CleanWebpackPlugin (), / / name of the folder to be cleaned],}

The index.html code is as follows

Webpack Button A Button B

The entry file main.js is as follows

Import A from'. / A 'import B from'. / B 'document.getElementById (' aBtn'). Onclick = function () {alert (A)} document.getElementById ('bBtn'). Onclick = function () {alert (B)}

The code for A.js and B.js is as follows

/ / A.js const A = 'hello A' module.exports = A / / B.js const B = 'hello B' module.exports = B

At this point, we npm run build the project and only two files are packaged.

Index.html

Index.js

Thus, at this time, webpack packages two files that main.js depends on into the same js file at the same time, and introduces it in index.html. But A.js and B.js are the logic that will be executed by clicking the corresponding button, if the user does not click the corresponding button, and the two files are relatively large, does this lead to the default loading of the js file on the home page is too large, resulting in slow rendering of the home page? So is it possible to load the corresponding dependent file when the user clicks the button?

Webpack.ensure solved this problem.

Require.ensure asynchronous loading

Let's change main.js to load asynchronously.

Document.getElementById ('aBtn') .onclick = function () {/ / asynchronously loaded A require.ensure ([], function () {let A = require ('. / A.js') alert (A)})} document.getElementById ('bBtn') .onclick = function () {/ / asynchronously loaded b require.ensure ([]) Function () {let B = require ('. / B.js') alert (B)})}

At this point, we packed it again and found that there were two more files, 1.index.js and 2.index.js. When we open the page, only the index.js file is introduced, the 1.index.js file is introduced when button An is clicked, and the 2.index.js file is introduced when button B is clicked. This meets our demand for on-demand loading.

The require.ensure function is a code-separated splitter, indicating that the require in the callback is the one we want to split out, that is, require ('. / A.js') to split the A.js into a separate js file packaged with webpack. Its syntax is as follows

Require.ensure (dependencies: String [], callback: function (require), chunkName: String)

We open the 1.index.js file and find that its code is as follows

(windowwindow.webpackJsonp = window.webpackJsonp | | []) .push ([[1], [, function (o, n) {o.exports = 'hello A'},],])

As can be seen from the above code:

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Asynchronously loaded code is saved in a global webpackJsonp.

The value of webpackJsonp.push, the two parameters are the id corresponding to the modules to be installed in the asynchronously loaded file and the list of modules to be installed in the asynchronously loaded file.

Under certain circumstances, the code in the specific module is executed.

Import () load on demand

Webpack4 official documentation provides modules to cut and load on demand. With es6's on-demand load import () method, you can reduce the home page package volume and speed up the request speed of the home page. Only other modules will load the corresponding js only when needed.

The syntax of import () is very simple. This function takes only one argument, which is the address of the reference package, and uses a promise-style callback to get the loaded package. All modules in the code that are import () will be packed into a separate package and placed in the directory where chunk is stored. When the browser runs to this line of code, the resource is automatically requested to load asynchronously.

Let's change the above code to import ().

Document.getElementById ('aBtn'). Onclick = function () {/ / Asynchronous loading An import ('. / A'). Then ((data) = > {alert (data.A)})} document.getElementById ('bBtn'). Onclick = function () {/ / Asynchronous loading b import ('. / B'). Then ((data) = > {alert (data.B)})}

At this point, the packaged file is the same as the webpack.ensure method.

Routing lazy loading

Why do you need lazy loading?

Single-page applications like vue, if there is no routing lazy loading, the files packaged with webpack will be very large, resulting in too much content to load when entering the home page, resulting in a white screen for a long time, the use of routing lazy loading can divide the page and load the page only when needed, which can effectively share the loading pressure borne by the home page and reduce the loading time of the home page.

Vue routing lazily contains the following three ways

Vue asynchronous component

Import () of ES6

Require.ensure () of webpack

Vue asynchronous component

This method mainly uses the asynchronous mechanism of resolve and uses require instead of import to realize on-demand loading.

Export default new Router ({routes: [{path:'/ home',', component: (resolve) = > require (['@ / components/home'], resolve),}, {path:'/ about',', component: (resolve) = > require (['@ / components/about'], resolve),},],})

Require.ensure

This mode allows the js to be packaged separately through the webpackChunkName in the parameter.

Export default new Router ({routes: [{path:'/ home', component: (resolve) = > require.ensure ([], () = > resolve (require ('@ / components/home')), 'home'),}, {path:' / about', component: (resolve) = > require.ensure ([], () = > resolve (require ('@ / components/about') 'about'),},],})

Import () of ES6

Vue-router provides a way on the official website, understandably and through Promise's resolve mechanism. Because the Promise returned by the Promise function is the resolve component itself, and we can use import to import the component.

Export default new Router ({routes: [{path:'/ home', component: () = > import ('@ / components/home'),}, {path:'/ about', component: () = > import ('@ / components/home'),},],})

Webpack subcontracting strategy

In the process of webpack packaging, there is often a large single file of vendor.js and app.js, which happens to be the first file to be loaded on the web page, which will make the loading time too long, thus making the white screen time too long, affecting the user experience. So we need to have a reasonable subcontracting strategy.

CommonsChunkPlugin

Before the Webapck4.x version, we all used CommonsChunkPlugin for separation

Plugins: [new webpack.optimize.CommonsChunkPlugin ({name: 'vendor', minChunks: function (module, count) {return (module.resource & & / .js $/ .test (module.resource) & & module.resource.indexOf (path.join (_ dirname,'. / node_modules')) = = 0)},}) New webpack.optimize.CommonsChunkPlugin ({name: 'common', chunks:' initial', minChunks: 2,}),]

Let's separate the following documents and pack them.

Under the node_modules folder, module

Modules shared by three ingress chunk

Optimization.splitChunks

The biggest change in webpack 4 is the abolition of CommonsChunkPlugin and the introduction of optimization.splitChunks. If your mode is production, then webpack4 will automatically turn on Code Splitting.

Its built-in code segmentation strategy is as follows:

Whether the new chunk is shared or is it a module from node_modules

Is the new chunk volume larger than 30kb before compression

The number of concurrent requests for demand loading chunk is less than or equal to 5

The number of concurrent requests when the page is initially loaded is less than or equal to 3

Although Code Splitting will be turned on automatically in webpack4, with the maximum of the project, this often can not meet our needs, and we need to make personalized optimization.

Application example

Let's first find a project with more room for optimization to operate. This is a background management system project, most of the content is developed by 3-4 front-ends, usually the development cycle is short, and most people do not have a sense of optimization, just write business code to complete the requirements, the days are long, resulting in large packaged files, greatly affecting performance.

We first use webpack-bundle-analyzer to analyze the packaged module dependencies and file size to determine the direction of optimization.

Then let's take a look at the packaged js file.

When I saw these two pictures, I was devastated. The slots are as follows.

After packaging, a number of nearly 1m js files are generated, including large files that must be loaded on the vendor.js home page.

Plug-ins such as xlsx.js are not necessary. A better way to export excel is to return the file stream format to the front end for processing.

The echart and iview files are too large and should use the method introduced by cdn

After complaining, we should get down to business. It is because there are so many slots that we are better able to verify the feasibility of our optimization method.

Pull away from echart and iview

From the above analysis, we can see that the echart and iview files are too large, so we use webpack4's optimization.splitChunks to split the code, separate them and package them into files. (in order to better show the optimization effect, let's remove the xlsx.js first.)

The vue.config.js is modified as follows:

ChainWebpack: config = > {config.optimization.splitChunks ({chunks: 'all', cacheGroups: {vendors: {name:' chunk-vendors', test: / [/] node_modules [/] /, priority: 10, chunks: 'initial'}, iview: {name:' chunk-iview' Priority: 20, test: / [/] node_modules [/] _? iview (. *) /}, echarts: {name: 'chunk-echarts', priority: 20, test: / [/] node_modules [/] _? echarts (. *) /} Commons: {name: 'chunk-commons', minChunks: 2, priority: 5, chunks:' initial', reuseExistingChunk: true})}

At this point, let's use webpack-bundle-analyzer to analyze it.

Packaged js file

From this we can see that we have successfully extracted echart and iview separately, and vendor.js has reduced the volume accordingly. In addition, we can continue to extract more third-party modules.

CDN mode

Although the third-party module is extracted separately, it is not conducive to performance optimization to load such a file of several hundred kb when the home page or the corresponding route is loaded. At this point, we can introduce such plug-ins or UI component libraries in a CDN way.

1. Introduce corresponding cdn links in index.html

1. Vue.config.js configure externals

ConfigureWebpack: (config) = > {config.externals = {vue: 'Vue', xlsx:' XLSX', iview: 'iView', iView:' ViewUI',}}

1. Remove the previous introduction method and uninstall the corresponding npm dependency package

Npm uninstall vue iview echarts xlsx-save

At this time, let's take a look at the situation after packing.

Packaged js file

Well done! At this time, there are basically no large files packaged, and the vendor.js needed to load the home page is only dozens of kb, and we can further optimize it by introducing some modules of the vue family bucket through the cdn method, such as vue-router,vuex,axios and so on. At this point, the loading performance of the page, especially the home page, is greatly optimized.

Thank you for reading, the above is the content of "what is the principle of asynchronous loading of webpack". After the study of this article, I believe you have a deeper understanding of what the principle of asynchronous loading of webpack is, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

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