zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    PBR(基于物理的渲染)学习笔记
    iOS应用千万级架构开篇
    iOS应用千万级架构:性能优化与卡顿监控
    iOS应用千万级架构:自动埋点与曝光
    iOS应用千万级架构:存储持久化
    iOS应用千万级架构:MVVM框架
    Spring Boot入门系列(十七)整合Mybatis,创建自定义mapper 实现多表关联查询!
    Spring Boot入门系列(十六)使用pagehelper实现分页功能
    Spring Boot入门系列(十五)Spring Boot 开发环境热部署
    说迷茫
  • 原文地址:https://www.cnblogs.com/moran1992/p/11233419.html
Copyright © 2011-2022 走看看