本指南包含一些提高构建/编译性能的实用技巧。
以下最佳实践将有所帮助,无论您是在开发还是生产中运行构建脚本。
使用最新版本的 webpack。我们一直在进行性能改进。最新推荐的 webpack 版本是
保持Node.js最新也可以提高性能。除此之外,保持您的包管理器(例如npm
或yarn
)最新也有帮助。较新版本创建更高效的模块树并提高解析速度。
将加载器应用于最少数量的必要模块。而不是
module.exports = {
//...
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
},
],
},
};
使用include
字段仅应用实际需要转换的加载器模块
const path = require('path');
module.exports = {
//...
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
},
],
},
};
每个额外的加载器/插件都有一个启动时间。尽量使用尽可能少的工具。
以下步骤可以提高解析速度
resolve.modules
、resolve.extensions
、resolve.mainFiles
、resolve.descriptionFiles
中的项目数量,因为它们会增加文件系统调用的数量。npm link
或yarn link
),请设置resolve.symlinks: false
。resolve.cacheWithContext: false
。使用DllPlugin
将更改频率较低的代码移到单独的编译中。这将提高应用程序的编译速度,尽管它会增加构建过程的复杂性。
减少编译的总大小以提高构建性能。尽量保持代码块小巧。
SplitChunksPlugin
。SplitChunksPlugin
的 async
模式。thread-loader
可用于将昂贵的加载器卸载到工作池。
在 webpack 配置中使用 cache
选项。在 package.json
中的 "postinstall"
中清除缓存目录。
对它们进行性能分析,避免引入性能问题。
可以通过从 webpack 的配置中移除 ProgressPlugin
来缩短构建时间。请记住,ProgressPlugin
对于快速构建可能没有那么大的价值,因此请确保您正在利用使用它的优势。
以下步骤在开发中特别有用。
使用 webpack 的 watch 模式。不要使用其他工具来监视您的文件并调用 webpack。内置的 watch 模式将跟踪时间戳并将此信息传递给编译以进行缓存失效。
在某些设置中,监视会回退到轮询模式。对于许多被监视的文件,这会导致大量的 CPU 负载。在这种情况下,您可以使用 watchOptions.poll
增加轮询间隔。
以下实用程序通过在内存中编译和提供资产来提高性能,而不是写入磁盘
webpack-dev-server
webpack-hot-middleware
webpack-dev-middleware
Webpack 4 默认情况下会使用其 stats.toJson()
输出大量数据。在增量步骤中,除非必要,否则避免检索 stats
对象的某些部分。v3.1.3 之后的 webpack-dev-server
包含一个实质性的性能修复,以最大程度地减少每次增量构建步骤从 stats
对象检索的数据量。
注意不同 devtool
设置之间的性能差异。
"eval"
具有最佳性能,但不会帮助您进行转译代码。cheap-source-map
变体性能更高。eval-source-map
变体。某些实用程序、插件和加载器只有在构建生产环境时才有意义。例如,在开发过程中,使用 TerserPlugin
对代码进行压缩和混淆通常没有意义。这些工具通常应该在开发中排除。
TerserPlugin
[fullhash]
/[chunkhash]
/[contenthash]
AggressiveSplittingPlugin
AggressiveMergingPlugin
ModuleConcatenationPlugin
Webpack 仅将更新的块输出到文件系统。对于某些配置选项(HMR、[name]
/[chunkhash]
/[contenthash]
在 output.chunkFilename
中、[fullhash]
),除了更改的块之外,入口块也会失效。
确保入口块通过保持其大小来廉价地发出。以下配置为运行时代码创建了一个额外的块,因此它生成起来很便宜
module.exports = {
// ...
optimization: {
runtimeChunk: true,
},
};
Webpack 会进行额外的算法工作来优化输出的大小和加载性能。这些优化对于较小的代码库来说性能很高,但在较大的代码库中可能很昂贵。
module.exports = {
// ...
optimization: {
removeAvailableModules: false,
removeEmptyChunks: false,
splitChunks: false,
},
};
Webpack 能够在输出包中生成路径信息。但是,这会给捆绑数千个模块的项目带来垃圾回收压力。在 `options.output.pathinfo` 设置中关闭此功能。
module.exports = {
// ...
output: {
pathinfo: false,
},
};
在 Node.js 版本 8.9.10 - 9.11.1 中,ES2015 的 `Map` 和 `Set` 实现存在 性能回归。Webpack 广泛使用这些数据结构,因此此回归会影响编译时间。
较早和较晚的 Node.js 版本不受影响。
为了在使用 `ts-loader` 时提高构建速度,请使用 `transpileOnly` 加载器选项。此选项本身会关闭类型检查。要重新启用类型检查,请使用 `ForkTsCheckerWebpackPlugin`。这通过将每个操作移到单独的进程中来加速 TypeScript 类型检查和 ESLint 代码风格检查。
module.exports = {
// ...
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true,
},
},
],
};
以下步骤在生产环境中特别有用。
源映射非常昂贵。你真的需要它们吗?
以下工具存在某些问题,可能会降低构建性能
happyPackMode: true
/ transpileOnly: true
中使用 ts-loader
。node-sass
存在一个 bug,它会阻止 Node.js 线程池中的线程。当与 thread-loader
一起使用时,请将 workerParallelJobs
设置为 2
。