webpack打包优化详解

举报
yd_244540595 发表于 2024/08/09 13:51:00 2024/08/09
【摘要】 作者:为了WLB努力链接:juejin.cn/post/7369485528708317221顺带吆喝一声,技术大厂,前后端测试捞人。先简单总结一下,优化Webpack打包可以通过多种方式来提高性能和减小文件大小。以下是一些常见的优化技巧:代码分割(Code Splitting):将代码拆分成多个小块,使得在加载页面时只加载必要的��码。Webpack提供了多种代码分割的方法,如使用impo...

作者:为了WLB努力
链接:juejin.cn/post/7369485528708317221

顺带吆喝一声,技术大厂,前后端测试捞人。

先简单总结一下,优化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来设置模块别名,减少模块路径的解析时间。

    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来进行图片压缩:

// 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来消除未使用的代码:

// webpack.config.js

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

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

 module.exports = {
  optimization: {
      minimizer: [new ESBuildPlugin()],
      splitChunks: {
        chunks: 'all', // 将所有类型的 chunks 进行分割,包括同步和异步的
        minSize: 10000, // 模块最小体积,将最小包体积降低到 10KB,以利用 HTTP/2 并行请求
        minRemainingSize: 0,
        minChunks: 1, // 模块最小被引用次数
        maxAsyncRequests: 30, // 按需加载时的最大并行请求数
        maxInitialRequests: 30, // 入口点的最大并行请求数
        enforceSizeThreshold: 50000, // 强制执行拆分的体积阈值
        automaticNameDelimiter: '~', // 文件名的连接符
        cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
      },
      
    },
};

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

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

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

    • defaultVendors:用于提取第三方库,它的 test 属性指定了匹配 node_modules 中的模块。priority 设置了优先级,值越大,优先级越高。

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


  3. 设置合理的分包阈值

通过设置合理的 minSizemaxSize 来控制包的大小,避免包太小导致请求次数增加或包太大导致加载时间过长:

module.exports = {
  optimization: {
    splitChunks: {
      minSize: 30000, // 最小包体积,根据具体情况测试分析,具体值以实际调试为准
      maxSize: 250000, // 最大包体积,根据具体情况测试分析,具体值以实际调试为准
    },
  },
};

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

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类型。例如:

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 选项来实现:

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

5.2. 并行构建(Parallelism)

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

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

5.3. 缓存组件(Caching Modules)

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

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

5.4. 模块缓存(Module Cache)

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

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

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。