Webpack打包效率優化篇


Webpack基礎配置:

語法解析:babel-loader

樣式解析:style-loader

css解析:css-loader

less解析:less-loader

文件解析:url-loader(file-loalder)

性能分析:webpack-bundle-analyzer

代碼:

var path = require('path');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
    mode: "development",
    entry: './app.js',
    output: {
        path: path.resolve(__dirname, './build/'),
        filename: "source.js",
    },
    devtool: "source-map",
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                }
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.(png|jpg|gif|svg|jpeg)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 1000 * 100
                        }
                    }
                ]
            },
            {
                test: /\.less$/,
                use: [
                    "style-loader",  // creates style nodes from JS strings
                    'css-loader',    // translates CSS into CommonJS
                    'less-loader',     // compiles Less to CSS
                ]
            },
        ]
    },
    plugins: [
        new BundleAnalyzerPlugin()
    ]
}

打包結果:

 

性能圖:

構建時間:8.506s

這里分析打包結果問題有哪些:

1.樣式文件沒有剝離出來

2.node_modules被打進來了

3.第三方打包體積過大react,react-dom

4.文件大小沒處理,沒有經過壓縮

好了針對以上幾個問題,我們重新配置webpack

1.剝離node_modules

rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                },
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    // 'style-loader',// 與 MiniCssExtractPlugin.loader 沖突 
                    'css-loader'
                ],
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    // "style-loader",  // creates style nodes from JS strings
                    'css-loader',    // translates CSS into CommonJS
                    'less-loader',     // compiles Less to CSS
                ],
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpg|gif|svg|jpeg)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 1000 * 100
                        }
                    }
                ],
                exclude: /node_modules/
            }
        ]

構建結果:

構建時間由8.506s變成1.251s

2.剝離js與css,less文件

webpack4.X版本已經使用最新API mini-css-extract-plugin ,原來的extract-text-webpack-plugin在node版本為10.X以后已經失效了。

引入plugin

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

配置loader

{
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    // 'style-loader',// 與 MiniCssExtractPlugin.loader 沖突 
                    'css-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    // "style-loader",  // creates style nodes from JS strings
                    'css-loader',    // translates CSS into CommonJS
                    'less-loader',     // compiles Less to CSS
                ]
            },

配置plugin

/**
         *  剝離CSS文件
         */
        new MiniCssExtractPlugin({
            filename: "[name].[chunkhash:8].css",
            chunkFilename: "[id].css"
        }),
        /** 
         *  動態引入css,less,js等文件
         */
        new HtmlWebpackPlugin({
            title: 'webpack',
            template: './index.html'
        }),

重新build

 

構建時間有1.251s變成1.391s這里剝離文件導致構建時間增加,但是我們可以看到生成的目標js體積由987K變成了886K

3.分離第三方類庫 DllPlugin 和 DllReferencePlugin

首先創建webpack.dll.config.js

const webpack = require('webpack');
const path = require('path');

module.exports = {
    entry: {
        react: [
            'react',
            'react-dom'
        ]
    },
    output: {
        filename: '[name].dll.js',
        path: path.resolve('distDll/dll'),
        library: '[name]_dll_[hash]'
    },
    plugins: [
        new webpack.DllPlugin({
            name: '[name]_dll_[hash]',
            path: path.join(__dirname, 'distDll/dll', '[name].manifest.json')
        })
    ]
}

在webpack.dev.js中增加

/**
         * 動態引入manifest.json
         */
        new webpack.DllReferencePlugin({
            context: __dirname,
            manifest: require('./distDll/dll/react.manifest.json')
        }),

構建結果

構建時間1.391s變成1.008s 目標體積由886K變成了9.92K

4.利用緩存加速二次構建

/**
         * 緩存加速二次構建速度
         */
        new HardSourceWebpackPlugin({
            cacheDirectory: 'node_modules/.cache/hard-source/[confighash]',
            configHash: function (webpackConfig) {
                // node-object-hash on npm can be used to build this.
                return require('node-object-hash')({ sort: false }).hash(webpackConfig);
            },
            environmentHash: {
                root: process.cwd(),
                directories: [],
                files: ['package-lock.json', 'yarn.lock'],
            },
            info: {
                // 'none' or 'test'.
                mode: 'none',
                // 'debug', 'log', 'info', 'warn', or 'error'.
                level: 'debug',
            },
            cachePrune: {
                maxAge: 2 * 24 * 60 * 60 * 1000,
                sizeThreshold: 50 * 1024 * 1024
            },
        }),

構建結果:

可以看到有寫入緩存的過程。這里代碼體積過小,沒看到加速效果,如果實際項目中,可以看到時間的縮小的效果

 5.利用scope histing (變量提升) 減少代碼閉包形成

這里我使用了兩個測試文件,a.js與b.js 其中b.js中引入了a.js

    /**
         * 開啟 Scope Hoisting
         */
        new webpack.optimize.ModuleConcatenationPlugin(),

配置前的效果:

可以清晰的看到打包之后的代碼分別對a.js與b.js生成了兩個閉包函數(閉包函數的副作用這里就不多說了,占內存)

build出的文件大小9.92K

配置后的效果:

 可以看到效果已經沒有了針對兩個兩個js的閉包代碼塊

我們可以看到目標文件大小由9.92K變成了8.98K

6.Tree shaking 刪除沒用的函數或者變量

在.babelrc文件中設置modules:false,其實webpack4中已經默認實現了tree shaking。

  /*
      tree shaking.
    */
    ["env", {
      "modules": false
    }],

我們在代碼中加入一個無效函數

var treeShaking = function () {
    console.log('tree shaking.');
    return;
    function unused() {
        return 'unused';
    };
}

treeShaking();

這里需要修改build模式更改為生產環境(production)而不是開發環境(development)

效果:

可以看到已經消除了unused函數。

7.壓縮圖片文件大小

   {
                test: /\.(png|jpg|gif|svg|jpeg)$/,
                use: [
                    'url-loader',
                    {
                        loader: 'image-webpack-loader',
                        // options: {
                        //     limit: 1000 * 100    //不加限制圖片過大會直接打到build下 導致找不到圖片文件
                        // }
                        options: {
                            mozjpeg: {
                                progressive: true,
                                quality: 65
                            },
                            // optipng.enabled: false will disable optipng
                            optipng: {
                                enabled: false,
                            },
                            pngquant: {
                                quality: '65-90',
                                speed: 4
                            },
                            gifsicle: {
                                interlaced: false,
                            },
                            // the webp option will enable WEBP
                            webp: {
                                quality: 75
                            }
                        }
                    }
                ],
                exclude: /node_modules/
            }

壓縮后的效果:

由壓縮前的79.6K變成了72.5K

最終build出的效果圖

可以看到已經壓縮到了很小。

以上關於webpack的優化先總結到這里,后續繼續更新。

github地址:https://github.com/Dqhan/Webpack


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM