webpack打包优化详解

先简单总结一下,优化Webpack打包可以通过多种方式来提高性能和减小文件大小。以下是一些常见的优化技巧:

  1. 代码分割(Code Splitting) :将代码拆分成多个小块,使得在加载页面时只加载必要的代码。Webpack提供了多种代码分割的方法,如使用import()函数、SplitChunksPlugin插件等。

  2. 懒加载(Lazy Loading):将不需要立即加载的模块延迟加载,提高页面初次加载速度。通常与代码分割一起使用。

  3. 压缩代码 :使用Webpack的UglifyJsPluginTerserPlugin等插件来压缩和混淆JavaScript代码,减小文件大小。

  4. 优化图片 :使用url-loaderfile-loader来处理图片,可以将小图片转换为Data URL,或者通过图片压缩工具来减小图片大小。

  5. Tree Shaking :通过Tree Shaking只打包项目中用到的代码,去除未使用的代码,减小打包体积。确保在Webpack配置中开启了Tree Shaking。注意,webpack5版本的树摇功能比webpack4版本做了很大改进,请升级到webpack5版本哦。

  6. 模块别名 :通过配置Webpack的resolve.alias来设置模块别名,减少模块路径的解析时间。

js 复制代码
    resolve: {// 设置模块如何被解析
      alias: {
        vue: "vue/dist/vue.esm-bundler.js"
      },
      extensions: ['.js', '.vue']// 按顺序解析这些后缀名
    },
  1. 提取公共代码 :使用SplitChunksPlugin或者optimization.splitChunks来提取公共代码,减少重复加载的代码,优化加载速度。

  2. 缓存 :通过设置output.filenameoutput.chunkFilename的hash值,使得文件名带有内容哈希,实现文件内容变化时,浏览器能够正确缓存文件。

  3. 使用Webpack Bundle Analyzer:分析打包后的文件,找出体积较大的模块或者文件,针对性进行优化。

  4. 减少loaderplugin的使用 :尽量减少不必要的loaderplugin的使用,因为它们会增加打包时间和文件大小。

  5. 使用DLLPlugin:将第三方库单独打包成一个动态链接库(DLL),可以减少每次打包时对第三方库的重新打包,提高打包速度。

  6. 缩小Webpack搜索范围 :通过配置resolve.modules、resolve.extensions、resolve.mainFields等参数,缩小Webpack搜索模块的范围,提高打包速度。

  7. 线上模式mode: 'production'和开发环境模式mode : 'development'要区分设置,并根据不同的环境模式设置不同的devtool值。

一起来实践吧

1.优化图片

除了用雪碧图和手动压缩图片大小,webpack也可以进一步自动化优化图片, 使用url-loaderfile-loader处理图片,并且结合image-webpack-loader来进行图片压缩:

js 复制代码
// webpack.config.js
module.exports = {
  // 其他配置...
  module: {
    rules: [
      {
        test: /.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192, // 小于 8KB 的图片将转换为 base64
              name: '[name].[hash:8].[ext]',
              outputPath: 'images',
            },
          },
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false,
              },
              pngquant: {
                quality: [0.65, 0.90],
                speed: 4
              },
              gifsicle: {
                interlaced: false,
              },
              webp: {
                quality: 75
              }
            },
          },
        ],
      },
    ],
  },
};

2.开启Tree Shaking

确保在Webpack配置中开启Tree Shaking来消除未使用的代码:

js 复制代码
// webpack.config.js

module.exports = {
  // 其他配置...
  optimization: {
    usedExports: true,
  },
};

3. 提取公共代码,进一步分包

js 复制代码
 optimization: {
      minimizer: [new ESBuildPlugin()],
      splitChunks: {
        cacheGroups: {
          defaultVendors: {
            name: 'chunk-vendors',
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
            chunks: 'initial'
          },
          common: {
            name: 'chunk-common',
            minChunks: 2,
            priority: -20,
            chunks: 'initial',
            reuseExistingChunk: true
          }
        }
      }
    },

这段配置使用了Webpack 5中的 optimization 选项,并结合了 ESBuildPlugin 进行代码压缩。同时,使用了 splitChunks 选项来进一步优化打包结果。

  1. minimizer: [new ESBuildPlugin()]:这里使用了 ESBuildPlugin 来进行代码压缩,它能够利用 ESBuild 引擎提供的快速压缩功能,提高构建效率。

  2. splitChunks:这个选项用于配置代码分割。在这个配置中,有两个 cacheGroups,分别是 defaultVendorscommon

    • defaultVendors:用于提取第三方库,它的 test 属性指定了匹配 node_modules 中的模块。priority 设置了优先级,值越大,优先级越高。chunks: 'initial' 表示只对入口模块进行代码分割。

    • common:用于提取共享模块,minChunks: 2 表示模块被引用至少两次时才会被提取。reuseExistingChunk: true 表示如果一个模块已经被提取过了,就会复用已经存在的模块,而不是再次创建一个新的模块。

这个配置能够有效地将第三方库和共享模块分割成独立的文件,以便利用浏览器的并行加载能力,提高应用的加载速度和性能。

4. 严格区分打包环境

在Webpack中,Source Map(源映射)是一种文件,它将编译后的代码映射回原始源代码。这对于调试和定位问题非常有用,因为它允许你在浏览器开发者工具中直接查看原始代码,而不是查看编译后的代码。Webpack支持多种类型的Source Map,你可以根据需求选择合适的类型。以下是一些常见的Source Map配置选项:

  1. eval: 将Source Map作为 DataURL嵌入到打包后的JavaScript文件中,不会生成额外的文件,但会增加打包时间。

  2. source-map : 生成单独的Source Map文件,以.map为后缀,对调试信息不作修改。

  3. cheap-source-map: 生成单独的Source Map文件,但不包含列信息,对调试信息进行简化,提高构建速度。

  4. cheap-module-source-map : 类似于cheap-source-map,同时对loader的Source Map也进行了处理,以便更好地定位到源代码中的错误位置。

  5. inline-source-map: 将Source Map数据以DataURL的形式嵌入到打包后的JavaScript文件中,不会生成额外的文件,但会增加打包体积。

  6. hidden-source-map: 生成单独的Source Map文件,但不在打包后的JavaScript文件中引用它,只在构建过程中用于调试。

  7. nosources-source-map: 生成单独的Source Map文件,但不包含源代码内容,用于发布生产环境版本。

你可以通过在Webpack配置文件中设置devtool选项来配置Source Map类型。例如:

javascript 复制代码
module.exports = {
  // 其他配置...
  devtool: 'source-map',
};

如果你需要在生产环境中生成Source Map,通常建议使用hidden-source-mapnosources-source-map等选项,以确保源代码的安全性,并减小打包体积。而在开发环境中,可以选择更详细的Source Map类型,以方便调试和定位问题。

5.充分利用webpack5的持久化缓存(Persistent Caching)

Webpack 5 提供了一些缓存优化的功能,可以显著提高构建性能。以下是一些Webpack 5 中的缓存优化方式:

5.1. 持久化缓存(Persistent Caching)

Webpack 5 引入了持久化缓存,可以将构建过程中生成的缓存结果保存到磁盘上,以便下次构建时直接使用缓存,而不需要重新构建所有模块。这可以通过在配置文件中添加 cache.typecache.buildDependencies 选项来实现:

javascript 复制代码
module.exports = {
  // 其他配置...
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename],
    },
  },
};

5.2. 并行构建(Parallelism)

Webpack 5 支持并行构建,可以同时处理多个构建任务,提高构建速度。你可以通过在配置文件中添加 parallel 选项来启用并行构建:

javascript 复制代码
module.exports = {
  // 其他配置...
  parallelism: 4, // 同时处理的任务数量
};

5.3. 缓存组件(Caching Modules)

Webpack 5 使用 moduleIds 来标识模块,并且默认情况下会对模块的导出进行 hash 编码。你可以使用 optimization.moduleIds 选项来自定义模块标识的生成方式:

javascript 复制代码
module.exports = {
  // 其他配置...
  optimization: {
    moduleIds: 'deterministic', // 可选值: 'deterministic', 'size', 'total-size', 'hashed'
  },
};

5.4. 模块缓存(Module Cache)

Webpack 5 支持模块级别的缓存,可以将经常引用的模块缓存起来,提高构建速度。你可以通过在配置文件中添加 cache 选项来启用模块缓存:

javascript 复制代码
module.exports = {
  // 其他配置...
  cache: {
    type: 'filesystem', // 持久化缓存
    cacheDirectory: path.resolve(__dirname, '.webpack_cache'), // 缓存目录
  },
};

通过使用这些缓存优化功能,Webpack 5 可以显著提高构建性能,尤其是对于大型项目和复杂项目来说,优化效果更加明显。

先写到这里,如果你还有想补充的,欢迎留言,一起学习交流哦!

相关推荐
hackeroink40 分钟前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者2 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-3 小时前
验证码机制
前端·后端
燃先生._.4 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖5 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235245 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
fantasy_arch5 小时前
CPU性能优化-磁盘空间和解析时间
网络·性能优化
m0_748240256 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar6 小时前
纯前端实现更新检测
开发语言·前端·javascript