webpack优化-- 优化代码压缩速度

809 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情

代码压缩

js压缩

webpack的代码压缩分为几个部分,其中重中之重是js,这一部分也是前端处理最多的。在webpack5种,官方内置了TerserPlugin来做压缩的优化。

如果你使用的是 webpack v5 或更高版本,同时希望自定义配置,那么仍需要安装 terser-webpack-plugin。如果使用 webpack v4,则必须安装 terser-webpack-plugin v4 的版本。

$ npm install terser-webpack-plugin --save-dev

然后将插件添加到你的 webpack 配置文件中。例如:

webpack.config.js

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

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

接下来,按照你习惯的方式运行 webpack

这里主要讲两个影响压缩速度的属性,exclude和parallel。

exclude主要用于进行目录的排除,做精准的打包匹配。因为一般情况下,我们引入的npm包,里面的文件都已经压缩和处理过了。所以我们可以排除node_modules,将需要压缩的范围缩小,只处理我们自己项目内文件的压缩。而外部引入的npm包,则直接使用npm包内的文件,不做特殊处理。

parallel多进程并发运行,将充分调动你的cpu,进行压缩的相关工作。默认值为os.cpus().length - 1

css分离

css压缩之前需要进行分离的动作, mini-css-extract-plugin插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。

首先,你需要安装 mini-css-extract-plugin

npm install --save-dev mini-css-extract-plugin

webpack配置

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  plugins: [new MiniCssExtractPlugin()],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
};

这个插件是基于webpack5的新特性构建,并且需要 webpack 5 才能正常工作。

与 extract-text-webpack-plugin 相比:

  • 异步加载
  • 没有重复的编译(性能)
  • 更容易使用
  • 特别针对 CSS 开发

css压缩

webpack5推荐使用 CssMinimizerWebpackPlugin来进行css的压缩,提供了打包匹配,并发,缓存等功能

首先,你需要安装 css-minimizer-webpack-plugin

$ npm install css-minimizer-webpack-plugin --save-dev

接着在 webpack 配置中加入该插件。示例:

webpack.config.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /.s?css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
    ],
  },
  optimization: {
    minimizer: [
      // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
      // `...`,
      new CssMinimizerPlugin(),
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
};

使用exclude和include来进行精确匹配,使用parallel来开启并发。

还有### minimizerOptions选项,因为本身该插件的底层是,Cssnano,这里将允许你使用更多的Cssnano的选项来优化你的css构建。

html压缩

html的压缩相对css和js来说,占比比较少,但是官方还是提供了 HtmlMinimizerWebpackPlugin来优化你的html打包。同样提供了精确匹配和并发的选项。 首先,你需要安装 html-minimizer-webpack-plugin

$ npm install html-minimizer-webpack-plugin --save-dev

接着在 webpack 配置中加入该插件。示例:

webpack.config.js

const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  module: {
    loaders: [
      {
        test: /.html$/i,
        type: "asset/resource",
      },
    ],
  },
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          context: path.resolve(__dirname, "dist"),
          from: "./src/*.html",
        },
      ],
    }),
  ],
  optimization: {
    minimize: true,
    minimizer: [
      // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
      // `...`
      new HtmlMinimizerPlugin(),
    ],
  },
};

图片压缩

ImageMinimizerWebpackPlugin是官方推荐的图片压缩工具,使用它后,将不再担心的你图片压缩和优化问题。

其底层使用两个工具

  • imagemin- 默认优化您的图像,因为它很稳定并且适用于所有类型的图像
  • squoosh- 在实验模式下使用.jpg.jpeg.png.webp,.avif文件类型工作时

首先,您需要安装image-minimizer-webpack-plugin

$ npm install image-minimizer-webpack-plugin --save-dev

图片压缩有两种模式可选,一种是无损,一种是有损

一般个人建议无损

npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev

如果需要有损的话,可以使用

npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const { extendDefaultPlugins } = require("svgo");

module.exports = {
  module: {
    rules: [
      {
        test: /.(jpe?g|png|gif|svg)$/i,
        type: "asset",
      },
    ],
  },
  plugins: [
    new ImageMinimizerPlugin({
      minimizerOptions: {
        // Lossless optimization with custom option
        // Feel free to experiment with options for better result for you
        plugins: [
          ["gifsicle", { interlaced: true }],
          ["jpegtran", { progressive: true }],
          ["optipng", { optimizationLevel: 5 }],
          // Svgo configuration here https://github.com/svg/svgo#configuration
          [
            "svgo",
            {
              plugins: extendDefaultPlugins([
                {
                  name: "removeViewBox",
                  active: false,
                },
                {
                  name: "addAttributesToSVGElement",
                  params: {
                    attributes: [{ xmlns: "http://www.w3.org/2000/svg" }],
                  },
                },
              ]),
            },
          ],
        ],
      },
    }),
  ],
};

我们可以通过includeexclude来决定哪些图片需要启用插件,哪些不启用

filter是一个函数,允许过滤图片是否启用压缩,true压缩,false不压缩。利用此选项,我们可以将大文件进行压缩,小文件不压缩

  new ImageMinimizerPlugin({
      filter: (source, sourcePath) => {
        // The `source` argument is a `Buffer` of source file
        // The `sourcePath` argument is an absolute path to source
        if (source.byteLength < 8192) {
          return false;
        }

        return true;
      },
    }),

maxConcurrency用于修改并发数量,默认Math.max(1, os.cpus().length - 1)