【性能优化】Webpack打包优化
查看依赖
分析依赖树,找出哪些模块占用了较多的资源。
webpack-bundle-analyzer
npm install --save-dev webpack-bundle-analyzer
webpack.config.js中添加插件配置:
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');module.exports = {// 其他配置项plugins: [// 其他插件new BundleAnalyzerPlugin({analyzerMode: 'static', // 生成静态报告文件openAnalyzer: false, // 构建完成后不会自动打开报告reportFilename: 'bundle-report.html' // 报告文件的名称})]
};
打包完成后,dist文件中多出bundle-report.html
文件,打开可以看到依赖占比。
一. 使用缓存
通过使用缓存,能够有效提升打包速度。
- webpack5以下:cache-loader
- webpack5:内置cache模块
内置cache模块
webpack5 内置了 cache 模块,缓存生成的 webpack 模块和 chunk,来改善构建速度。
在开发环境下,默认设置为 type: 'memory'
而在生产环境中被禁用。cache: { type: 'memory' }
与 cache: true
作用一样,可以通过设置 cache: { type: 'filesystem' }
来开放更多配置项。
module.exports = {cache: {type: 'filesystem',},
};
会在 node_modules 目录下生成一个 .cache 目录缓存文件内容,二次打包速度显著提升。
cache-loader
安装
npm install cache-loader -D
在 webpack.config.js 对应的开销大的 loader 前加上 cache-loader。
注意:如果使用多线程加载器如 thread-loader 时,也需要确保 cache-loader 放在 thread-loader 之前。
module.exports = {module: {rules: [{test: /\.js$/,use: ['cache-loader','babel-loader']}]}
}
二、多进程构建
同时开启多个 nodejs 进程进行构建
thread-loader
yarn add thread-loader -D
module.exports = {module: {rules: [{test: /.js$/,include: path.resolve('src'),use: ["thread-loader",// 耗时的 loader (例如 babel-loader)],},],},
};
注意:
使用时,需将此 loader 放置在其他 loader 之前,放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。
每个 worker 都是一个独立的 node.js 进程,开销大约为 600ms 左右。同时会限制跨进程的数据交换。所以请仅在耗时的操作中使用此 loader!(一般只在大型项目中的 ts、js 文件使用)
预编译资源模块
代替 cdn 分包,解决每个模块都得引用一个 script 的缺陷。
以 react 和 react-dom 为例,新建一个 webpack.dll.js 文件,用于预编译资源的打包,例如要对 react 和 react-dom 进行预编译,配置如下:
const path = require('path');
const webpack = require('webpack');module.exports = {mode: 'production',entry: {library: ['react', 'react-dom'],},output: {filename: 'react-library.dll.js',path: path.resolve(__dirname, './dll'),library: '[name]_[hash]', // 对应的包映射名},plugins: [new webpack.DllPlugin({context: __dirname,name: '[name]_[hash]', // 引用的包映射名path: path.join(__dirname, './dll/react-library.json'),}),],
};
package.json
中新增命令
{// ..."scripts": {// ..."build:dll": "webpack --config ./webpack.dll.js"},// ...
}
执行 npm run build:dll
后,webpack.config.js中:
const webpack = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');module.exports = {plugins: [new webpack.DllReferencePlugin({context: __dirname,manifest: require('./dll/react-library.json'),}),// 打包后的 .dll.js 文件需要引入到 html中,可以通过 add-asset-html-webpack-plugin 插件自动引入new AddAssetHtmlPlugin({ filepath: require.resolve('./dll/react-library.dll.js'),publicPath: '',}),],
};