【Webpack】性能优化

1)代码分割(Code Splitting)

  • Webpack 提供了 SplitChunksPlugin 插件,可以将代码分割成不同的包,减少单个包的体积。
  • 例如,使用动态 import (import()) 可以实现按需加载模块,提升加载速度。

以上两种也正是 实现条件组件的按需打包 的方式。

SplitChunksPlugin 将根据以下条件自动拆分 chunks:

  • 新的 chunk 可以被共享,或者模块来自于 node_modules 文件夹
  • 新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积)
  • 当按需加载 chunks 时,并行请求的最大数量小于或等于 30
  • 当加载初始化页面时,并发请求的最大数量小于或等于 30
module.exports = {
  // ...
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
};

splitChunks.chunks 选项设为 ‘all’,表示希望将所有类型的代码(包括同步和异步代码)都进行分割。

1)拆分策略:

  • chunks: 用于指定哪些模块需要拆分,有效值包括 'async'(只处理异步代码)、 'initial'(只处理同步代码)和 'all'(处理全部代码)。
  • minSize: 模块的最小大小,只有大于这个大小的模块才会被拆分,默认为 30KB。
  • maxSize: 模块的最大大小,超过这个大小的模块会被进一步拆分。
splitChunks: {
  chunks: 'all',
  minSize: 30000,
  maxSize: 0,
},

2)缓存组(cacheGroups):

  • cacheGroups: 在 splitChunks 的配置项中,你可以自定义不同的缓存组,用来指定哪些特定的模块或者库需要被单独打包。
splitChunks: {
  cacheGroups: {
    vendors: {
      test: /[\/]node_modules[\/]/,
      name: 'vendors',
      chunks: 'all',
    },
    common: {
      test: /[\/]src[\/]common[\/]/,
      name: 'common',
      minChunks: 2,
      chunks: 'all',
      reuseExistingChunk: true,
    },
  },
},

3) runtimeChunk 配置:

  • runtimeChunk: 用于将Webpack运行时的代码单独抽取出来。这样做的好处是可以更好地利用缓存,减少因Webpack运行时代码变动导致的缓存失效。
optimization: {
  runtimeChunk: 'single',
},

4)理解 importrequire

  • 要充分利用 Webpack 的代码分割功能,建议使用 ES6 动态 import() 语法来实现懒加载。相比于传统的 require.ensure()import() 语法更清晰、现代,而且有更好的支持。

2)压缩和混淆(Minification and Uglification)

  • Webpack 有 TerserPlugin 插件,可以压缩和混淆 JavaScript 代码,有效减少打包生成文件的体积。
  • CSS 也可以用 css-loaderMiniCssExtractPlugin 来进行压缩。

混淆代码(Code Obfuscation)是一种将代码变得难以阅读和理解的过程,目的是保护代码不被轻易复制或理解,防止他人窃取或修改你的代码逻辑。

混淆通常涉及以下几个方面:

  • 变量和函数名替换:将变量和函数名替换为简短、无意义的字符。例如,将 calculateTax 替换为 a 或 cT。

  • 删除元数据:移除代码中的注释、未使用的变量和函数,以及其他不必要的元数据。

  • 控制流改变:改变代码的控制流结构,例如使用复杂的条件和逻辑,使得代码难以跟踪和理解。

  • 字符串加密:将代码中的字符串进行加密或编码,使用时再进行解码。

  • 代码压缩:移除所有不必要的空格、换行和注释,减少代码的体积。

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  // ...
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()],
  },
};

3)树摇(Tree Shaking)

  • 通过 ES6 的模块化特性,Webpack 可以自动去除未使用的代码,从而减小打包后的文件大小。
  • 例如,在配置文件中设置 mode: 'production',会自动启用 Tree Shaking

4)异步加载(Lazy Loading)

  • 延迟加载重要的 JavaScript 模块,使用 import() 动态导入函数实现。
  • 例如,在路由配置中进行懒加载。

5)使用缓存(Caching)

  • Webpack 提供了 filename: '[name].[contenthash].js' 的命名方式,通过 hash 值标识文件版本。
  • 结合 HTTP 缓存机制,使得用户可以持久化缓存内容,减少重复加载。

6)图片优化

  • 使用 Webpack 插件 image-webpack-loader 压缩图片。
  • Lazy-Load图片,在用户即将滚动到图片可视区域时再进行加载。
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
          },
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65,
              },
              // optipng.enabled: false will disable optipng
              optipng: {
                enabled: false,
              },
              pngquant: {
                quality: [0.65, 0.90],
                speed: 4,
              },
              gifsicle: {
                interlaced: false,
              },
              // the webp option will enable WEBP
              webp: {
                quality: 75,
              },
            },
          },
        ],
      },
    ],
  },
};

7)充分利用插件

  • webpack-bundle-analyzer 插件可以分析项目的 bundle 大小和组成,发现和减少不必要的依赖。
  • 根据分析结果,进行相应的优化措施。

8)合理配置 externals 和 alias

  • 合理配置 externals 和 alias。通过配置 externals 来避免将某些库打入 bundle,减少打包体积;通过 alias 显式配置路径,提高编译速度。
module.exports = {
  externals: {
    jquery: 'jQuery',
  },
};

module.exports = {
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src/'),
      // 其他 alias
    },
  },
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秀秀_heo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值