webpack 打包构建优化实践

webpack 打包构建优化主要从两方面入手,一个是构建的速度,一个是打包的体积,针对不同的场景可以用不同的方式来进行优化,以下是 webpack 配置优化的一些常见手段。

  • 优化 webpack 构建速度,主要从几个方面入手,分别是定向查找、减少执行构建的模块、并行构建以提升总体的速度、并行压缩提高构建效率、合理使用缓存等,具体的配置如下:

    1. 定向查找:定向查找主要是配置 resolve 属性,通过指定路径和配置路径别名来优化查找路径等,缩短查找时间,配置如下:
    module.exports = {
        // ...其他配置
        resolve: {
            // 指定第三方模块的搜索路径,减少搜索步骤
            // 如果没有指定,则会从当前路径逐层向上查找
            modules: [path.resolve(__dirname, 'node_modules')],
            // 路径别名,可以减少书写繁琐的路径前缀,优化查找路径
            alias: {
                "@": path.resolve(__dirname, "src"),
                "_c": path.resolve(__dirname, "src/components")
            },
            // 在导入语句没有带文件后缀时,可以按照配置的列表,自动补上后缀
            // 可以把高频率的后缀放在最前,减少没有必要的匹配
            extensions: ['ts', 'tsx', 'js', 'jsx', 'scss']
        }
    }
    
    1. 减少执行构建的模块noParse 忽略没有模块化的文件(例如 JQuery、lodash)、合理配置loader的 includeexclude 属性等
    module.exports = {
        // ...其他配置
        module: {
            // 忽略没有模块化的文件
            noParse: /jquery|lodash/,
            rules: [
                {
                    test: /\.jsx?$/,
                    include: [path.resolve(__dirname, 'src')],
                    exclude: /node_modules/,
                    use: ['babel-loader']
                }
            ]
        }
    }
    
    1. 并行构建以提升总体的速度:可以使用 thread-loader 开启多个线程池进行并发执行构建,只有在代码量很多的时候开启多进程构建才会有明显的提升,因为官方也有说明,每一个 worker 需要耗费 600ms 的启动;
    module.exports = {
        // ...其他配置
        module: {
            rules: [
                {
                    test: /\.jsx?$/,
                    use: [
                        // 开启多线程
                        {
                            loader: 'thread-loader',
                            options: {
                                worker: 2
                            }
                        },
                        {
                            loader: 'babel-loader'
                        }
                    ]
                }
            ]
        }
    }
    
    1. 并行压缩提高构建效率:并行压缩主要是用了 terser-webpack-plugin,在 webpack5 中自带最新的 terser-webpack-plugin,在 mode:'production' 时会自动开启,如果想要自定义配置的话,仍然需要安装依赖 npm i terser-webpack-plugin --save-dev;
    const TerserPlugin = require("terser-webpack-plugin");
    module.exports = {
          optimization: {
              minimize: true,
              minimizer: [
                  new TerserPlugin({
                      // test     匹配文件的正则表达式
                      // include  包括哪些文件
                      // exclude  排除哪些文件
                      // parallel 使用多进程并行提高速度,默认是 os.cpus().length - 1
                      // terserOptions 配置选项
                      // extractComments 是否保留注释
                  }),
              ],
          },
    };
    
    1. 合理使用缓存: 利用 webpack5 的新特性 cache,首次构建会增加耗时,但是之后再次构建会大幅度提高构建速度;babel-loader 增加缓存等
    module.exports = {
        // ... 其他配置
        module: {
            rules: [
          		{
                    test: /\.jsx?/,
                    use: [
                        {
                            loader: 'babel-loader',
                            options: {
                                cacheDirectory: true,
                            }
                        }
                    ]
                }      
            ],
        },
        cache: {
            type: 'filesystem'
        }
    }
    
  • 优化 webpack 打包体积,主要从几个方面入手,分别是代码压缩、按需加载、提前加载、Code Splitting、Tree Shaking、Gzip、作用提升等,具体配置如下:

    1. 代码压缩:代码压缩主要压缩 html、css、js、image 文件,具体如下配置:
    const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
    const TerserPlugin = require("terser-webpack-plugin");
    module.exports = {
        optimization: {
            minimize: true, // 是否需要压缩
            minimizer: [
                new CssMinimizerPlugin({}), // 配置 css 压缩插件
                new TerserPlugin(), // 压缩 js 文件,生产环境默认开启,自定义选项时需要下载依赖重新配置
            ],
        },
        module: {
            rules: [
                // ... 其他配置
                {
                    test: /\.(png|jpg|gif|jpeg|webp|svg)$/,
                    use: [
                        "file-loader",
                        {
                            // 压缩图片的loader
                            loader: "image-webpack-loader",
                            options: {
                                mozjpeg: {
                                    progressive: true,
                                },
                                optipng: {
                                    enabled: false,
                                },
                                pngquant: {
                                    quality: [0.65, 0.9],
                                    speed: 4,
                                },
                                gifsicle: {
                                    interlaced: false,
                                },
                            },
                        },
                    ],
                },
            ]
        },
        plugins: [
            new HtmlWebpackPlugin({
                template: "./index.html", // 动态生成 html 文件
                minify: {
                    removeComments: true, // 移除HTML中的注释
                    collapseWhitespace: true, // 删除空⽩符与换⾏符
                    minifyCSS: true // 压缩内联css
                },
            })
        ]
    }
    
    1. 按需加载:按需加载主要依赖于 import 语法,主要分为配置第三方UI库按需加载、路由懒加载、import('xx').then()语法等来实现按需加载;

    2. Code Splitting:代码分割主要是将公共的代码进行抽离,放到一个公共文件,这样不仅可以减少文件体积,也可以做到只要文件内容不变,就可以从浏览器缓存中读取,这里主要是用 SplitChunksPlugin进行分割,具体配置如下:

    module.exports = {
        //...其他配置
        optimization: {
            splitChunks: {
                chunks: 'all', // 值有 all/async/initial/function,表示选择哪些 chunk 进行优化
                minSize: 20000, // 生成 chunk 的最小体积。
                minRemainingSize: 0,
                minChunks: 1, // 拆分前必须共享模块的最小 chunks 数。
                maxAsyncRequests: 30, // 按需加载时的最大并行请求数。
                maxInitialRequests: 30, // 入口点的最大并行请求数。
                enforceSizeThreshold: 50000, // 强制执行拆分的阈值
                cacheGroups: {
                    defaultVendors: {
                        test: /[\/]node_modules[\/]/, // 匹配的路径文件
                        priority: -10, // 缓存的优先级
                        reuseExistingChunk: true, // 复用当前 chunk 包含已从主 bundle 中拆分出的模块
                    },
                    default: {
                        minChunks: 2,
                        priority: -20,
                        reuseExistingChunk: true,
                    },
                },
            },
        },
    };
    
    1. Tree Shaking

      • 清除没有用到的 js、css 代码,主要依赖于 esmodule 的特性,可以在 package.json 中配置 sideEffects:false 选项,表示对所有文件进行 tree shaking,但是会有一定的影响,比如导入 polyfill 包,这种会被处理掉,导致样式丢失和失去 polyfill 的作用,这明显不是我们要的结果,那么基于这种情况,我们可以进一步对 sideEffects 做配置,举个例子,以下代码表示遇到数组中的模块,就跳过,不进行 tree shaking 操作;
      {
          "sideEffects": ["@babel/poly-fill", "*.less"]
      }	
      
      • css 代码进行 tree shaking 需要借助 purgecss-webpack-plugin 插件,配置如下
      const PurgecssPlugin = require("purgecss-webpack-plugin");
      const glob = require("glob");
      module.exports = {
          // ...其他配置
          plugins: [
              new PurgecssPlugin({
                  // 这里我的样式在根目录下的index.html里面使用,所以配置这个路径
                  paths: glob.sync(`${path.join(__dirname)}/**/*.css`, { nodir: true }),
              })
          ]
      }
      
    2. Gzip:Gzip 是对资源进行进一步的压缩,当浏览器支持 gzip 时,服务器返回 gzip 包,浏览器接收到 gzip 包后就进行解压操作,我们可以借助 compression-webpack-plugin 插件来打包;

      const CompressionWebpackPlugin = require("compression-webpack-plugin");
      module.exports = {
          // ...其他配置
          plugins: [
              new CompressionWebpackPlugin()
          ]
      }
      
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Webpack 是一个非常强大的打包工具,但是在处理大型项目时可能会出现性能问题。以下是一些优化 Webpack 性能的方法: 1. 减少打包的入口文件数量:每个入口文件都需要单独处理,因此减少入口文件数量可以减少处理时间。 2. 使用 Tree Shaking:Tree Shaking 是一个通过静态分析来消除未使用代码的技术。它可以大大减少打包后的文件大小。 3. 使用代码分割:代码分割可以将代码拆分成更小的块,以便在需要时才加载它们。这可以减少初始加载时间并提高性能。 4. 使用缓存:使用缓存可以避免不必要的重新编译,提高构建速度。可以使用 webpack 的缓存插件或者使用缓存-loader。 5. 使用多线程构建Webpack 4 引入了一个新的配置选项,可以通过设置 parallel 来启用多线程构建,这可以加速构建过程。 6. 使用 HappyPack:HappyPack 可以将任务分解成多个子进程并发执行,加速构建过程。 7. 使用动态链接库:将一些稳定的第三方库打包成动态链接库,可以减少每次重新编译时的处理时间。 8. 拆分长期缓存:将长期缓存的文件拆分成多个小文件,可以减少每次重新构建时的处理时间。 9. 压缩代码:使用压缩工具可以减小文件大小,并提高加载速度。 这些方法并不是全部,Webpack 有很多配置选项可以优化性能。通过实践和学习,可以找到最适合自己项目的优化方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值