Webpack打包效率优化篇

Posted moran1992

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于Webpack打包效率优化篇的主要内容,如果未能解决你的问题,请参考以下文章

webpack性能优化——构建效率

Webpack 打包优化之体积篇

Webpack 打包优化之体积篇

[转] Webpack 打包优化之体积篇

图解Webpack——优化篇

减少 Webpack 打包时间