webpack5性能优化

性能分析工具

1. 编译进度条

通过 progress-bar-webpack-plugin 插件查看编译进度,方便我们掌握编译情况。

npm i -D progress-bar-webpack-plugin

webpack.common.js 配置方式如下:

const chalk = require("chalk");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
module.exports = {
  plugins: [
    // 进度条
    new ProgressBarPlugin({
      format: `:msg [:bar] ${chalk.green.bold(":percent")} (:elapsed s)`,
    }),
  ],
};

2. 编译速度分析

通过 speed-measure-webpack-plugin 插件进行构建速度分析,可以看到各个 loader、plugin 的构建时长,后续可针对耗时 loader、plugin 进行优化。

npm i -D speed-measure-webpack-plugin

webpack.dev.js 配置方式如下:

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
  // ...webpack config...
});

3. 打包体积分析

使用 webpack-bundle-analyzer 查看打包后生成的 bundle 体积分析,将 bundle 内容展示为一个便捷的、交互式、可缩放的树状图形式。帮助我们分析输出结果来检查模块在何处结束。

webpack.prod.js 配置方式如下:

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = {
  plugins: [
    // 打包体积分析
    new BundleAnalyzerPlugin(),
  ],
};

优化开发体验

webpack.dev.js 配置方式如下:

const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");

module.exports = {
  devServer: {
    contentBase: "./dist",
    hot: true,
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new ReactRefreshWebpackPlugin(),
  ],
};

加快构建速度

1. cache

通过配置 webpack 持久化缓存 cache: filesystem,来缓存生成的 webpack 模块和 chunk,改善构建速度。

webpack.common.js 配置方式如下:

module.exports = {
  cache: {
    type: "filesystem", // 使用文件缓存
  },
};

2. 减少 loader、plugins

每个的 loader、plugin 都有其启动时间。尽量少地使用工具,将非必须的 loader、plugins 删除。

3. 指定include、exclude

const path = require('path');

module.exports = {
  rules: [
    {
      test: /\.(js|ts|jsx|tsx)$/,
      exclude: /node_modules/,
      include: [
        path.resolve(__dirname, 'src')
      ],
      use: [
        {
          loader: "esbuild-loader",
          options: {
            loader: "tsx",
            target: "es2015",
          },
        },
      ],
    },
  ],
};

4. 管理资源

使用 webpack 资源模块 (asset module) 代替旧的 assets loader(如 file-loader/url-loader/raw-loader 等),减少 loader 配置数量。

const path = require('path');

module.exports = {
  rules: [
    {
      test: /\.(png|svg|jpg|jpeg|gif)$/i,
      include: [
        path.resolve(__dirname, 'src')
      ],
      type: "asset/resource",
    },
  ],
};

5. 优化 resolve 配置

resolve 用来配置 webpack 如何解析模块,可通过优化 resolve 配置来覆盖默认配置项,减少解析范围。

const path = require('path');

module.exports = {
  // 指定目录可缩小 webpack 解析范围,加快构建速度。
  modules: ["node_modules", path.resolve(__dirname, 'src')],
  module: {
    //不需要解析依赖的第三方大型类库等,可以通过这个字段进行配置,以提高构建速度
    //使用 noParse 进行忽略的模块文件中不会解析 import、require 等语法
    noParse: /jquery|lodash/,
    rules: []
  },
  resolve: {
    alias: {
      "@": path.resolve(__dirname, 'src'), // @ 代表 src 路径
    },
    extensions: [".tsx", ".js"], // 项目用到的文件类型。
    symlinks: false, //如果项目不使用symlinks(例如 npm link 或者 yarn link),可以设置resolve.symlinks: false,减少解析工作量。
  },
  // 从输出的bundle中排除,从CDN引入
  externals: {
    react: 'react',
    moment: 'moment',
    antd: 'antd',
    lodash: 'lodash',
  }
};

6. 多进程

通过 thread-loader 将耗时的 loader 放在一个独立的 worker 池中运行,加快 loader 构建速度。

const path = require('path');

module.exports = {
  rules: [
    {
      test: /\.module\.(scss|sass)$/,
      include: path.resolve(__dirname, 'src'),
      use: [
        "style-loader",
        {
          loader: "css-loader",
          options: {
            modules: true,
            importLoaders: 2,
          },
        },
        {
          loader: "postcss-loader",
          options: {
            postcssOptions: {
              plugins: [["postcss-preset-env"]],
            },
          },
        },
        {
          loader: "thread-loader",
          options: {
            workerParallelJobs: 2,
          },
        },
        "sass-loader",
      ].filter(Boolean),
    },
  ],
};

减小打包体积

1. JS 压缩

使用 TerserWebpackPlugin 来压缩JavaScript。

webpack5 自带最新的 terser-webpack-plugin,无需手动安装。

terser-webpack-plugin 默认开启了 parallel: true 配置,并发运行的默认数量: os.cpus().length - 1 ,本文配置的 parallel 数量为 4,使用多进程并发运行压缩以提高构建速度。

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

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: 4,
        // extractComments:默认值为true,表示会将注释抽取到一个单独的文件中;
        // 在开发中,我们不希望保留这个注释时,可以设置为false;
        extractComments: false,
        terserOptions: {
          parse: {
            ecma: 8,
          },
          compress: {
            ecma: 5,
            warnings: false,
            comparisons: false,
            inline: 2,
          },
          mangle: {
            safari10: true,
          },
          output: {
            ecma: 5,
            comments: false,
            ascii_only: true,
          },
        },
      }),
    ],
  },
};

2. CSS 压缩

使用 CssMinimizerWebpackPlugin 压缩 CSS 文件。

optimize-css-assets-webpack-plugin 相比,css-minimizer-webpack-plugin 在 source maps 和 assets 中使用查询字符串会更加准确,而且支持缓存和并发模式下运行。

CssMinimizerWebpackPlugin 将在 Webpack 构建期间搜索 CSS 文件,优化、压缩 CSS。

webpack.prod.js 配置方式如下:

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

module.exports = {
  optimization: {
    minimizer: [
      new CssMinimizerPlugin({
        parallel: 4,
      }),
    ],
  },
};

3. 代码分离

3.1 抽离重复代码

SplitChunksPlugin 插件开箱即用,可以将公共的依赖模块提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk。

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

  • 新的 chunk 可以被共享,或者模块来自于 node_modules 文件夹;
  • 新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积);
  • 当按需加载 chunks 时,并行请求的最大数量小于或等于 30;
  • 当加载初始化页面时,并发请求的最大数量小于或等于 30; 通过 splitChunks 把 react 等公共库抽离出来,不重复引入占用体积。

注意:切记不要为 cacheGroups 定义固定的 name,因为 cacheGroups.name 指定字符串或始终返回相同字符串的函数时,会将所有常见模块和 vendor 合并为一个 chunk。这会导致更大的初始下载量并减慢页面加载速度。

module.exports = {
  splitChunks: {
    // include all types of chunks
    chunks: "all",
    // 重复打包问题
    cacheGroups: {
      vendors: {
        // node_modules里的代码
        test: /[\\/]node_modules[\\/]/,
        chunks: "all",
        // name: 'vendors', 一定不要定义固定的name
        priority: 10, // 优先级
        enforce: true,
      },
    },
  },
};

3.2 CSS文件分离

MiniCssExtractPlugin 插件将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const isEnvProduction = process.env.NODE_ENV === 'production';

module.exports = {
  plugins: [new MiniCssExtractPlugin()],
  module: {
    rules: [
      {
        test: /\.module\.(scss|sass)$/,
        include: [path.resolve(__dirname, 'src')],
        use: [
          "style-loader",
          isEnvProduction && MiniCssExtractPlugin.loader, // 仅生产环境
          {
            loader: "css-loader",
            options: {
              modules: true,
              importLoaders: 2,
            },
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [["postcss-preset-env"]],
              },
            },
          },
          {
            loader: "thread-loader",
            options: {
              workerParallelJobs: 2,
            },
          },
          "sass-loader",
        ].filter(Boolean),
      },
    ],
  },
};

4. 组件库按需引用

babel.config.js配置:

module.exports = {
  plugins: [
    ['import', { libraryName: 'antd' }],
    "lodash"
  ]
}

5. CDN

将大的静态资源上传至 CDN:

  • 字体:压缩并上传至 CDN;
  • 图片:压缩并上传至 CDN。

6. 按需加载

通过 webpack 提供的 import()语法 动态导入功能进行代码分离,通过按需加载,大大提升网页加载速度。

懒加载 JS 脚本的方式

  • CommonJS:require.ensure
  • ES6:动态import (目前还没有原生支持,需要babel转换)

如何使用动态import

  • 安装babel插件
npm i @babel/plugin-syntax-dynamic-import --save-dev
  • 引入在.babelrc文件的根目录下
{
  "plugins" : [
    "@babel/plugin-syntax-dynamic-import"
  ]
}
 function loadComponent() {
    import('./text.js').then((Text) => {
      this.setState({
        Text: Text.default
      })
    })
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
webpack可以通过以下几个方面进行性能优化: 1. 构建性能优化:可以通过减少模块解析、优化loader性能、限制loader的应用、缓存loader的结果等方式来提升构建性能。 2. 传输性能优化:可以通过分包策略来减少文件大小,包括手动分包和自动分包。同时,可以对模块体积进行优化,例如代码压缩和tree shaking等技术。 3. 运行性能优化:可以使用辅助工具来提升运行性能,例如开启热替换、启用多线程打包、懒加载以及使用gzip压缩等。 另外,为了进一步提升Webpack的性能,可以使用一些插件。比如,可以使用CssMinimizerWebpackPlugin插件来优化和压缩CSS文件。此插件会在Webpack构建过程中搜索CSS文件并对其进行优化。 另外,通过配置Webpack的持久化缓存选项,可以使用缓存来提高构建速度。可以通过设置`cache: filesystem`来缓存生成的Webpack模块和chunk,以改善构建速度。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [webpack之常见性能优化](https://blog.csdn.net/Mr_RedStar/article/details/123462435)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [webpack5性能优化](https://blog.csdn.net/momei1942/article/details/129682636)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值