Webpack优化方案

对于Webpack的优化方案,可以从以下几个方面入手

  • 提升体验
  • 提升打包构建速度
  • 减小包体积
  • 优化代码运行性能

提升体验

  1. Source Map

        我们通过webpack打包后的文件一般都会经过一些处理,比如代码压缩,文件合并等,使得最终打包产生的文件与实际开发时有很大区别,在这种情况下,如果代码报错,根据浏览器提示的报错信息是无法知道出错的具体位置的。

        Source Map就是为了解决这一问题

        Source Map就是一个信息文件,存储着代码转换前的位置信息,浏览器通过这个文件,可以直接找到代码的原始位置,而不是转换后的代码,为开发带来很大的方便

const path = require('path');
module.exports = (env) => {
    return {
        mode: 'development',
        entry: {
            main: './src/main.js',
        },
        output: {
            path: path.resolve(__dirname, './dist'),
            clean: true,
        },
        // source-map配置
       devtool: 'source-map',
    }
}

         Source Map常用配置项

  •  cheap-module-source-map :  只包含映射行,不包含列,打包速度块,适合生产模式
  •  source-map:包含行/列映射,打包速度慢,适合开发模式
     

提升打包构建速度

  1. HotModuleReplacement(热更新):开发时只编译打包发生变化的代码,对于不变的代码使用缓存,提高更新速度。
    只需要在webpack-dev-server中将hot设置true即可,webpack4.0以上默认配置。
  2. OneOf: 在进行资源模块处理时,通过OneOf配置资源被某loader处理就不会继续遍历了。
    module.exports = {
    //解析资源模块
    module: {
                rules: [
                    //...
                    {
                        //oneOf: 只使用第一个匹配的规则
                        oneOf: [
                            {
                                test: [/\.css$/],
                                use: getStyleLoaders()
                            },
                            {
                                test: [/\.s[ac]ss$/],
                                use: getStyleLoaders("sass-loader")
                            }]
                    }
                ]
        }
    }
  3. Include/extend:只包含或排除某文件,使处理文件更少,提高打包速度
    比如这里通过include配置只针对当前Src文件下的js/ts/tsx文件做进行babel代码转换
                     module: {                    
                            {
                                test: [/\.(tsx?|js)$/],
                                // babel- loader:转换js代码
                                include: paths.appSrc,
                                loader: require.resolve('babel-loader'),
                                options: {
                                    //对指定目录的转换做缓存
                                    cacheDirectory: true,
                                   //... 
                                },
                            },
                      }
  4. Cache:对babel和eslint处理结果缓存,提高打包速度
  5. runtimeChunk:生成一个runtime文件用来存储所有文件地址,当一个文件发生变化时,只更新变化文件和runtime文件,依赖这个文件的其他文件不受影响。
    output: {
                path: paths.appBuild,
                filename: isEnvProduction
                    ? 'static/js/[name].[contenthash:8].js'
                    : isEnvDevelopment && 'static/js/[name].js',
                clean: true,
                //懒加载包名称(用到时加载)
                chunkFilename: isEnvProduction
                    ? 'static/js/[name].[contenthash:8].chunk.js'
                    : isEnvDevelopment && 'static/js/[name].chunk.js',
                assetModuleFilename: 'static/media/[name].[contenthash:8][ext][query]',
            },
    //....

    首先在设置输出的文件名时,通过contenthash保证文件名根据文件内容进行变化来设置缓存。
    同时配置runtimeChunk,他会将文件之间的依赖关系(文件地址 hash值)提取成单独的一个runtime文件,保证A文件变化时, 只有runtime文件和A文件发生变化,其他文件不变。

    optimization: {          
      runtimeChunk: isEnvProduction && {
                    // 保存引入文件的模块的依赖文件,当引入模块更新时,只需更新当前文件和runtime即可,    无需更新其他依赖文件
                    name: (entrypoint) => `runtime~${entrypoint.name}`  //entrypoint 入口文件
                }
    }
  6. Thead:多进程处理eslint和babel,提高速度(需根据实际文件大小进行衡量)

减小包体积

  1. tree-shaking:移除JS中多余的代码
    module.exports = {
     optimization: {
       usedExports: true,
     },
    };
  2. babel/plugin-transform-runtime:  babel在编译每个文件时,都会注入一些辅助代码,使得文件体积过大,通过这一插件,在处理babel时,通过引入辅助代码的方式,而不是让每个文件都生成辅助代码,以减少文件体积。
    {
                        test: [/\.js$/],
                        exclude: path.resolve(__dirname, '../node_modules'),
                        loader: require.resolve('babel-loader'),
                        options: {
                                    //对指定目录的转换做缓存
                                    cacheDirectory: true,
                                    //会使用 Gzip 压缩每个 Babel transform 输出
                                    cacheCompression: false,
                                    plugins: [
                                        //引入辅助代码的方式
                                        "@babel/plugin-transform-runtime",
                                    ]
                                }
                    }
  3. 图片压缩

  4. 代码压缩

     optimization: {
                //...
                minimizer: [
                    //js代码压缩
                    new TerserPlugin({
                        terserOptions: {
                            compress: {
                                //是否输出警告
                                warnings: false,
                 // 是否删除代码中所有的console语句,默认为不删除,开启后,会删除所有的console语句
                                drop_console: true,
                            },
                            output: {
                                //是否保留注释
                                comments: false,
                            }
                        }
                    }
                    ),
                    //CSS压缩
                    new CssMinimizerPlugin(),
                    // 压缩图片
                    new ImageMinimizerPlugin({
                        minimizer: {
                            implementation: ImageMinimizerPlugin.imageminGenerate,
                            options: {
                                plugins: [
                                    ["gifsicle", { interlaced: true }],
                                    ["jpegtran", { progressive: true }],
                                    ["optipng", { optimizationLevel: 5 }],
                                    [
                                        "svgo",
                                        {
                                            plugins: [
                                                "preset-default",
                                                "prefixIds",
                                                {
                                                    name: "sortAttrs",
                                                    params: {
                                                        xmlnsOrder: "alphabetical",
                                                    },
                                                },
                                            ],
                                        },
                                    ],
                                ],
                            },
                        },
                    }),
                ],
    }

优化代码运行性能 

  1. code split : 对代码进行分块打包,使单文件体积更小,并行加载速度更快
      optimization: {
                splitChunks: {
                    chunks: 'all',//所有模块进行分割
                    cacheGroups: {//打包模块组
                        react: {//组名
                            //react react-dom
                            test: /[\\/]node_modules[\\/]react(.*)?[\\/]/,
                            name: 'chunk-react',
                            priority: 50,
                        },
                        antd: {
                            test: /[\\/]node_modules[\\/]antd[\\/]/,
                            name: 'chunk-antd',
                            priority: 30,
                        },
                        lid: {
                            test: /[\\/]node_modules[\\/]/,
                            name: 'chunk-libs',
                            priority: 1,
                            // reuseExistingChunk: true,
                        },
                    },
                },
    }

    这里分别针对了react/antd模块进行单独打包,然后对其他模块统一打包

  2. 按需加载:通过import动态导入进行按需加载
    document.getElementById("btn").onclick = function () {
      import('./count')
        .then((res) => {
           console.log("模块加载成功" + res); 
        })
        .catch(err => {
        console.log("模块加载失败" + err);
      })
    }

    这样只有在点击btn按钮时才会加载count文件,而不是页面一加载就加载count文件。
    再比如vue中的路由懒加载也是通过这一方法实现。

  3. preload/prefetch
    preload:告诉浏览器立即加载资源,只加载当前页面资源
    new PreloadWebpackPlugin({
        rel:'preload',
        as:'script'
    })
    prefetch:空闲时加载资源,也可以加载下一页面使用的资源
    new PreloadWebpackPlugin({
        rel:'prefetch',
    })

    他们都是只加载,不执行,当使用相关资源时,会运行加载之前的缓存
  4. core-js:js兼容处理,能够在低版本浏览器中运行。(处理babel不能处理不了的,包括async函数、promise对象、数组的一些方法等)

       

        

webpack 是一个非常强大的前端打包工具,但是在项目逐渐复杂的情况下,构建速度打包输出的体积很容易成为瓶颈。以下是一些 webpack 优化的方法: 1. 使用高版本的 webpack:每个版本的 webpack 性能都会有所提升,升级到最新版本是一个很不错的优化方案。 2. 使用 webpack-bundle-analyzer:该插件可以帮助你分析打包出来的代码大小依赖关系,从而更好地优化代码。 3. 使用 DllPlugin DllReferencePlugin:这两个插件可以将一些基础库(如 React、Vue 等)分离出来,从而减少每次打包的时间。 4. 开启多进程/多实例构建:使用 webpack-parallel-uglify-plugin 或 thread-loader 插件,可以让 webpack 开启多个进程或者多个实例来处理任务,从而提升构建速度。 5. 使用 Tree Shaking:Tree Shaking 是一个很强大的工具,可以帮助我们删除掉不需要的代码,减小打包后的文件大小。 6. 合理使用缓存:使用 cache-loader 或者 hard-source-webpack-plugin 插件可以让 webpack 更好地利用缓存,从而提升构建速度。 7. 使用 code splitting:使用 webpack 的 code splitting 功能,可以让我们将代码分成多个块,从而提升加载速度并行加载能力。 8. 按需加载:按需加载可以让我们只加载需要的代码,减少不必要的网络请求加载时间。 以上是一些常见的 webpack 优化方法,当然还有很多其他的方法,具体要根据项目的实际情况进行优化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值