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 可以显著提高构建性能,尤其是对于大型项目和复杂项目来说,优化效果更加明显。

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

相关推荐
桂月二二36 分钟前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb2 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角2 小时前
CSS 颜色
前端·css
浪浪山小白兔3 小时前
HTML5 新表单属性详解
前端·html·html5
lee5763 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579653 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter
limit for me4 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者4 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
qq_392794484 小时前
前端缓存策略:强缓存与协商缓存深度剖析
前端·缓存