[TOC]
1, the background
At present, our website project adopts multiple pages, and development and reconstruction are separated. When developing new pages, since the reconstruction development may often add style files or adjust style order, the team adopts the following development modeAs we get more pages and more style files to rely on,gulp
As the number of tasks increases, the problem of slow packaging and compilation is gradually exposed. The packaging time in this mode is shown in the following screenshot:You can seegulp
Mission approximately required30s
, required by the Webpack task30s
Add up to over a minute for the first build and around 8 seconds for the second build. Imagine this scenario popping out of your head every time you build. Is that bearable? It can be seen that we have come to the point where we must change, ok
So I decided to modify the current build method, divided into the following steps
1, remove thegulp
The modified mode is shown in the following figure, in which green is the new process, which is removed compared with the original processgulp
packagingcss
The process is handed over insteadwebpack
To deal withAfter switching to this mode, the first packaging takes about 20 seconds and incremental compilation takes about 8 seconds
2,webpack
Optimization of construction speed
2.1 exclude include
To optimize the
Specify the files that need to be processed and excluded in the matching rule, narrow the search and processing scope of files, and ensure that as few files as possible are compiled. Add the corresponding include and exclude configurations as follows
rules: [
{
test: /\.[jt]s$/,
include: [path.resolve(process.cwd(), 'src')].exclude: [/node_modules/, path.resolve(process.cwd(), 'src/vendor')]}, {test: /\.css$/,
include: RESOURCES.CSS.cwd,
}
]
Copy the code
With the above configuration, the first packaging time is about 16s and the incremental compilation time is about 8s
2.2 thread-loader
andesbuild-loader
To optimize the
Thread-loader adopts multi-process packaging, and the loader placed behind thread-loader will run in a separate worker pool. Esbuild is a tool developed by Go for packaging and compression of TS and JS, characterized by fast packaging speed. It’s dozens or even hundreds of times faster than WebPack, rollup, and Parcel, but esBuild doesn’t support CSS yet and doesn’t have plug-ins, so it’s not a replacement for WebPack. Vite and Snowpack both use esBuild. The key configurations are as follows
const cpuNum = require('os').cpus().length;
const tsWorkerPool = {
workers: 6.poolTimeout: Infinity
};
const cssWorkerPool = {
workers: cpuNum - tsWorkerPool.workers,
poolTimeout: Infinity
};
threadLoader.warmup(tsWorkerPool, ['esbuild-loader']);
threadLoader.warmup(cssWorkerPool, ['css-loader']);
module: {
rules: [{test: /\.[jt]s$/,
use: [
{
loader: 'thread-loader'.options: tsWorkerPool
},
{
loader: 'esbuild-loader'.options: {
loader: 'ts'.target: 'es2015'.tsconfigRaw: require('.. /tsconfig.json')}}, {loader: path.resolve(__dirname, 'loaders/importcss-loader.js'),
options: {
include: path.resolve(process.cwd(), 'src/app'),}},],include: [path.resolve(process.cwd(), 'src')].exclude: [/node_modules/, path.resolve(process.cwd(), 'src/vendor')]}, {test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'thread-loader'.options: cssWorkerPool
},
{
loader: 'css-loader'.options: {
esModule: false,}}, {loader: 'esbuild-loader'.options: {
loader: 'css'.minify: true}}].include: RESOURCES.CSS.cwd,
}
],
},
Copy the code
After testing, with the addition of Thread-loader, the first packaging time is about 12s, and the incremental compilation time is about 3s. With the addition of esbuild-Loader, the first packaging time is about 8s, and the incremental compilation time is about 2s. https://esbuild.github.io/api/#target for most grammar esbuild mentioned in document – loader only support convert to es6, so only suitable for use in a development environment, production environment is not recommended
2.3 Image compression and removing redundant CSS style files
The image compression configuration is as follows
Loader: 'image-webpack-loader', options: {// Enable compression in production environment disable: process.env.node_env === 'production'? False: true, // compress JPG /jpeg image mozjpeg: {progressive: true, quality: 80 // compression ratio}, // compress PNG image pngquant: {quality: [0.65, 0.90], speed: 4}}Copy the code
Use the purgECSS plug-in to remove redundant styles. The configuration is as follows, and the configuration needs to be added for special ones that cannot be removed
new PurgecssPlugin({ paths: glob.sync([ path.resolve(__dirname, '../../server/views/**/*.html'), path.resolve(`${PATH.SRC}/**/*.vue`), ]), safelist: [/data-v-.*/, // vue scope style reserved /market-message/, // handle the marketing notification bar background color is determined by the configuration.Copy the code
3. Upgrade towebpack5
webpack
It was released last yearwebpack5
Many optimizations are introduced, including: 1. Persistent caching is enabled by default and cached in memory, whilewebpack4
You need to usecache-loader
andhard-source-webpack-plugin
To do caching 2.NodeJS
thepolyfill
Script is removed while inwebpack4
And in previous versions, for mostNode
Modules will be added automaticallypolyfill
Script, resulting in a larger volume after packaging. 3. BetterTreeShaking
After the above optimization, I want to further test itwebpack5
Version can bring optimization effect, willwebpack
Upgrade packages and dependencies to the latest version and remove incompatible onesspeed-measure-webpack-plugin
And what is no longer neededhard-source-webpack-plugin
After the plugin, processing about 65 files, the first packaging time reduced to6.5 s
Around, incremental compilation time1.5 s
Around, you can see that the time is further shortened.
4. Hot loading and hot updating
Add the following configuration to webpack.dev.js
devServer: {
contentBase: path.join(PATH.DIST, 'js'),
inline: true,
compress: true,
port: 5000,
writeToDisk: true,
host: '0.0. 0. 0',
hot: true,
disableHostCheck: true,
headers: {
'Access-Control-Allow-Origin': 'https://www.midasbuy.com',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Credentials': true,}},Copy the code
Since we use the Whistle agent for domain name access during development and inform whistle of file updates through Websocket, we need to add the following rules in Whistle. The first rule is to establish a Websocket connection. The second content is used to request update when hot update, which mainly realizes the hot update of VUE components and hot refresh of JS, while the hot update of CSS has not been realized temporarily.
https://www.midasbuy.com:5000 http://127.0.0.1:5000/ ^ https://www.midasbuy.com/oversea_web/static/ * * * * * * hot - update http://127.0.0.1:5000/oversea_web/static/$1hot-update$2Copy the code
Pit: Test hot refresh, modify the file, page refresh display the following errorThen manual refresh again, along the way did not find the reason, once also suspected iswhistle
The agent’s reason, later suspected, was to send notification update instructions too early, and then wrote onehack
Method to delay sending the update instruction, found that it was ok, but the specific reason was not found, until the switch to the server terminal, update the file saw the following printI get it. Here’s how we do itclient
After compiling the file, the end copies the file toserver
Folder below to provide forejs include
Come in and use it,server
Using thenodemon
When the file changes, the file copy operation is triggerednodemon
Restart causes the browser to restartreload
When the request failed, so the resolution is innodemon
The directory of the copied file is omitted from the configuration file because what is actually copied is<style link='*****'></style>
and<script src='*****'></script>
This content, so completely can be ignored, ignored after the file changes will not restart the server, problem solved.
5,vue devtools
Locate the component directory
In view of the component selection provided by Vue DevTools in the browser, you can directly open the compiler and open the source code file of the component. The following configuration is added under webpack.dev.js in the reference documentation
const openInEditor = require('launch-editor-middleware'); devServer: { ... before(app) { app.use('/__open-in-editor', openInEditor('code', path.resolve(process.cwd(), 'src'))); }},Copy the code
Add a line of rules to whistle
https://www.midasbuy.com/__open-in-editor http://127.0.0.1:5000/__open-in-editor
Copy the code
As shown below, clicking the circled position will openvscode
Editor and navigate to the component’s corresponding source file code
6, summary
In the test environment of MacBook Pro Intel Core I7 16G memory 250G hard disk size, the compilation time under different schemes and the size of main files before gzip compression are compared as follows. In the case of processing about 65 files, it can be seen that the compilation time is greatly shortened and the size of JS files is also reduced. However, the size of the style file has increased because some of the images have been base64 encoded into CSS.
plan | First compilation time | Second compilation time | buypage.js |
propsOrder.js |
buypage.css |
propsOrder.css |
---|---|---|---|---|---|---|
gulp +webpack4 |
60s |
8s |
178kb |
157kb |
17.58 KB |
24.74 KB |
webpack5 |
6.5 s |
1.5 s |
123kb |
112kb |
28kb |
35kb |