diff --git a/src/content/guides/build-performance.mdx b/src/content/guides/build-performance.mdx index f24100e1942b..5b37b67aa593 100644 --- a/src/content/guides/build-performance.mdx +++ b/src/content/guides/build-performance.mdx @@ -11,6 +11,7 @@ contributors: translators: - QC-L - jacob-lcs + - Yucohny --- 本指南包含一些改进构建/编译性能的实用技巧。 @@ -19,19 +20,19 @@ translators: ## 通用环境 $#general$ -无论你是在 [开发环境](/guides/development) 还是在 [生产环境](/guides/production) 下运行构建脚本,以下最佳实践都会有所帮助。 +无论是在 [开发环境](/guides/development) 还是在 [生产环境](/guides/production) 下运行构建脚本,以下最佳实践都会有所帮助。 ### 更新到最新版本 $#stay-up-to-date$ -使用最新的 webpack 版本。我们会经常进行性能优化。webpack 的最新稳定版本是: +使用最新的 webpack 版本。我们会一直坚持进行性能优化。webpack 的最新稳定版本是: [![latest webpack version](https://img.shields.io/github/package-json/v/webpack/webpack.svg?label=webpack&style=flat-square&maxAge=3600)](https://github.com/webpack/webpack/releases) -将 **Node.js** 更新到最新版本,也有助于提高性能。除此之外,将你的 package 管理工具(例如 `npm` 或者 `yarn`)更新到最新版本,也有助于提高性能。较新的版本能够建立更高效的模块树以及提高解析速度。 +将 **Node.js** 与 package 管理工具(例如 `npm` 或者 `yarn`)更新到最新版本均有助于提高性能。较新的版本能够建立更高效的模块树并提高解析速度。 ### loader $#loaders$ -将 loader 应用于最少数量的必要模块。而非如下: +将 loader 应用于最少数量的必要模块。反例: ```js module.exports = { @@ -47,7 +48,7 @@ module.exports = { }; ``` -通过使用 `include` 字段,仅将 loader 应用在实际需要将其转换的模块: +使用 `include` 字段将 loader 应用在实际需要将其转换的模块: ```js const path = require('path'); @@ -66,7 +67,7 @@ module.exports = { }; ``` -### 引导(bootstrap) $#bootstrap$ +### 引导(bootstrap) $#bootstrap$ 每个额外的 loader/plugin 都有其启动时间。尽量少地使用工具。 @@ -75,80 +76,80 @@ module.exports = { 以下步骤可以提高解析速度: - 减少 `resolve.modules`, `resolve.extensions`, `resolve.mainFiles`, `resolve.descriptionFiles` 中条目数量,因为他们会增加文件系统调用的次数。 -- 如果你不使用 symlinks(例如 `npm link` 或者 `yarn link`),可以设置 `resolve.symlinks: false`。 -- 如果你使用自定义 resolve plugin 规则,并且没有指定 context 上下文,可以设置 `resolve.cacheWithContext: false`。 +- 如果不使用 symlinks(例如 `npm link` 或者 `yarn link`),可以设置 `resolve.symlinks: false`。 +- 如果使用自定义解析插件规则,并且没有指定上下文,可以设置 `resolve.cacheWithContext: false`。 ### dll $#dlls$ -使用 `DllPlugin` 为更改不频繁的代码生成单独的编译结果。这可以提高应用程序的编译速度,尽管它增加了构建过程的复杂度。 +使用 `DllPlugin` 为更改不频繁的代码生成单独的编译结果。尽管这增加了构建过程的复杂度,但是可以提高应用程序的编译速度。 -### 小即是快(smaller = faster) $#smaller--faster$ +### 小即是快 $#smaller--faster$ -减少编译结果的整体大小,以提高构建性能。尽量保持 chunk 体积小。 +减少编译结果的整体大小以提高构建性能。尽量保持 chunk 体积小。 -- 使用数量更少/体积更小的 library。 +- 使用数量更少/体积更小的库 - 在多页面应用程序中使用 `SplitChunksPlugin`。 -- 在多页面应用程序中使用 `SplitChunksPlugin `,并开启 `async` 模式。 -- 移除未引用代码。 -- 只编译你当前正在开发的那些代码。 +- 在多页面应用程序中使用 `SplitChunksPlugin`,并开启 `async` 模式。 +- 移除未使用的代码。 +- 只编译当前正在开发的那些代码。 -### worker 池(worker pool) $#worker-pool$ +### worker 池 $#worker-pool$ -`thread-loader` 可以将非常消耗资源的 loader 分流给一个 worker pool。 +`thread-loader` 可以将非常消耗资源的 loader 分流给 worker 池。 -W> 不要使用太多的 worker,因为 Node.js 的 runtime 和 loader 都有启动开销。最小化 worker 和 main process(主进程) 之间的模块传输。进程间通讯(IPC, inter process communication)是非常消耗资源的。 +W> 由于 Node.js 运行时与 loader 都有启动开销,尽量不要使用太多 worker,尝试最小化 worker 与主进程之间的模块传输。进程间通讯非常消耗资源。 ### 持久化缓存 $#persistent-cache$ 在 webpack 配置中使用 [`cache`](/configuration/cache) 选项。使用 `package.json` 中的 `"postinstall"` 清除缓存目录。 -T> 我们支持 yarn PnP v3 [`yarn 2 berry`](https://yarnpkg.com/features/pnp),来进行持久缓存。 +T> 我们支持使用 yarn PnP v3 [`yarn 2 berry`](https://yarnpkg.com/features/pnp) 进行持久缓存。 ### 自定义 plugin/loader $#custom-pluginsloaders$ -对它们进行概要分析,以免在此处引入性能问题。 +请在使用自定义 plugin/loader 前对其进行概要分析以免在此处引入性能问题。 -### Progress plugin $#progress-plugin$ +### Progress 插件 $#progress-plugin$ -将 `ProgressPlugin` 从 webpack 中删除,可以缩短构建时间。请注意,`ProgressPlugin` 可能不会为快速构建提供太多价值,因此,请权衡利弊再使用。 +将 `ProgressPlugin` 从 webpack 中删除可以缩短构建时间。请注意,`ProgressPlugin` 可能不会为快速构建提供太多价值,因此请权衡利弊再使用。 --- ## 开发环境 $#development$ -以下步骤对于 _开发环境_ 特别有帮助。 +以下步骤在开发环境中特别有帮助。 ### 增量编译 $#incremental-builds$ -使用 webpack 的 watch mode(监听模式)。而不使用其他工具来 watch 文件和调用 webpack 。内置的 watch mode 会记录时间戳并将此信息传递给 compilation 以使缓存失效。 +使用 webpack 的观察模式,而非使用其他工具观察文件、调用 webpack。内置的观察模式会记录时间戳并将此信息传递给编译以使缓存失效。 -在某些配置环境中,watch mode 会回退到 poll mode(轮询模式)。监听许多文件会导致 CPU 大量负载。在这些情况下,可以使用 `watchOptions.poll` 来增加轮询的间隔时间。 +在某些配置环境中,观察模式会回退到轮询模式。监听过量文件会导致 CPU 大量负载。此时可以使用 `watchOptions.poll` 增加轮询的间隔时间。 ### 在内存中编译 $#compile-in-memory$ -下面几个工具通过在内存中(而不是写入磁盘)编译和 serve 资源来提高性能: +使用下面几个工具实现在内存中(而不是写入磁盘)编译并部署可访问资源以提高性能: - `webpack-dev-server` - `webpack-hot-middleware` - `webpack-dev-middleware` -### stats.toJson 加速 $#statstojson-speed$ +### 加速 stats.toJson $#statstojson-speed$ -webpack 4 默认使用 `stats.toJson()` 输出大量数据。除非在增量步骤中做必要的统计,否则请避免获取 `stats` 对象的部分内容。`webpack-dev-server` 在 v3.1.3 以后的版本,包含一个重要的性能修复,即最小化每个增量构建步骤中,从 `stats` 对象获取的数据量。 +webpack 4 默认使用 `stats.toJson()` 输出大量数据。但是除非在增量步骤中做必要的统计,否则请避免获取 `stats` 对象的部分内容。`webpack-dev-server` 在 v3.1.3 以后的版本,包含一个重要的性能修复,即最小化每个增量构建步骤中会从 `stats` 对象获取的数据量。 -### Devtool $#devtool$ +### devtool $#devtool$ -需要注意的是不同的 `devtool` 设置,会导致性能差异。 +不同的 `devtool` 设置会导致性能差异。 -- `"eval"` 具有最好的性能,但并不能帮助你转译代码。 -- 如果你能接受稍差一些的 map 质量,可以使用 `cheap-source-map` 变体配置来提高性能 +- `"eval"` 具有最好的性能,但并不能帮助转译代码。 +- 如果能接受稍差一些的映射质量,可以使用 `cheap-source-map` 变体配置提高性能。 - 使用 `eval-source-map` 变体配置进行增量编译。 T> 在大多数情况下,最佳选择是 `eval-cheap-module-source-map`。 -### 避免在生产环境下才会用到的工具 $#avoid-production-specific-tooling$ +### 避免使用在生产环境下才会用到的工具 $#avoid-production-specific-tooling$ -某些 utility, plugin 和 loader 都只用于生产环境。例如,在开发环境下使用 `TerserPlugin` 来 minify(压缩) 和 mangle(混淆破坏) 代码是没有意义的。通常在开发环境下,应该排除以下这些工具: +某些工具、插件与 loader 都只用于生产环境。例如,在开发环境下使用 `TerserPlugin` 压缩和破坏代码是没有意义的。通常应该在开发环境下排除以下工具: - `TerserPlugin` - `[fullhash]`/`[chunkhash]`/`[contenthash]` @@ -156,11 +157,11 @@ T> 在大多数情况下,最佳选择是 `eval-cheap-module-source-map`。 - `AggressiveMergingPlugin` - `ModuleConcatenationPlugin` -### 最小化 entry chunk $#minimal-entry-chunk$ +### 最小化入口 chunk $#minimal-entry-chunk$ -Webpack 只会在文件系统中输出已经更新的 chunk。某些配置选项(HMR, `output.chunkFilename` 的 `[name]`/`[chunkhash]/[contenthash]`,`[fullhash]`)来说,除了对已经更新的 chunk 无效之外,对于 entry chunk 也不会生效。 +webpack 只会在文件系统中输出已经更新的 chunk。对于某些配置选项(HMR, `output.chunkFilename` 中的 `[name]`/`[chunkhash]/[contenthash]`,`[fullhash]`)而言,除了已更新的 chunk 之外,入口 chunk 也会失效。 -确保在生成 entry chunk 时,尽量减少其体积以提高性能。下面的配置为运行时代码创建了一个额外的 chunk,所以它的生成代价较低: +尽量在生成入口 chunk 时减小其体积以提高性能。下面的配置为运行时代码创建了一个额外的 chunk,所以它的生成代价较低: ```js module.exports = { @@ -173,7 +174,7 @@ module.exports = { ### 避免额外的优化步骤 $#avoid-extra-optimization-steps$ -Webpack 通过执行额外的算法任务,来优化输出结果的体积和加载性能。这些优化适用于小型代码库,但是在大型代码库中却非常耗费性能: +webpack 通过执行额外的算法任务优化输出结果的体积和加载的性能。这些优化适用于小型代码库,但是在大型代码库中却非常耗费性能: ```js module.exports = { @@ -188,7 +189,7 @@ module.exports = { ### 输出结果不携带路径信息 $#output-without-path-info$ -Webpack 会在输出的 bundle 中生成路径信息。然而,在打包数千个模块的项目中,这会导致造成垃圾回收性能压力。在 `options.output.pathinfo` 设置中关闭: +webpack 会在输出的 bundle 中生成路径信息。然而,在打包数千个模块的项目中,这会带来垃圾回收性能的压力。在 `options.output.pathinfo` 设置中关闭它: ```js module.exports = { @@ -201,13 +202,13 @@ module.exports = { ### Node.js 版本 8.9.10-9.11.1 $#nodejs-versions-8910-9111$ -Node.js v8.9.10 - v9.11.1 中的 ES2015 `Map` 和 `Set` 实现,存在 [性能回退](https://github.com/nodejs/node/issues/19769)。Webpack 大量地使用这些数据结构,因此这次回退也会影响编译时间。 +Node.js v8.9.10 - v9.11.1 中的 ES2015 `Map` 和 `Set` 实现,存在 [性能回退](https://github.com/nodejs/node/issues/19769)。webpack 大量地使用这些数据结构,因此这些回退也会影响编译时间。 之前和之后的 Node.js 版本不受影响。 ### TypeScript loader $#typescript-loader$ -你可以为 loader 传入 `transpileOnly` 选项,以缩短使用 `ts-loader` 时的构建时间。使用此选项,会关闭类型检查。如果要再次开启类型检查,请使用 [`ForkTsCheckerWebpackPlugin`](https://www.npmjs.com/package/fork-ts-checker-webpack-plugin)。使用此插件会将检查过程移至单独的进程,可以加快 TypeScript 的类型检查和 ESLint 插入的速度。 +向 loader 传入 `transpileOnly` 选项,以缩短使用 `ts-loader` 时的构建时间。使用此选项会关闭类型检查。如果要再次开启类型检查,请使用 [`ForkTsCheckerWebpackPlugin`](https://www.npmjs.com/package/fork-ts-checker-webpack-plugin)。使用此插件会将检查过程移至单独的进程,这样可以加快 TypeScript 的类型检查和 ESLint 插入的速度。 ```js module.exports = { @@ -224,19 +225,19 @@ module.exports = { }; ``` -T> 这是一个关于 `ts-loader` [完整示例](https://github.com/TypeStrong/ts-loader/tree/master/examples/fork-ts-checker-webpack-plugin)的 Github 仓库。 +T> 这是一个关于 `ts-loader` [完整示例](https://github.com/TypeStrong/ts-loader/tree/master/examples/fork-ts-checker-webpack-plugin) 的 GitHub 仓库。 --- ## 生产环境 $#production$ -以下步骤对于 _生产环境_ 特别有帮助。 +以下步骤在生产环境中特别有帮助。 -W> **不要为了很小的性能收益,牺牲应用程序的质量!** 注意,在大多数情况下,优化代码质量比构建性能更重要。 +W> **不要为了很小的性能收益,牺牲应用程序的质量**!注意,在大多数情况下,优化代码质量比构建性能更重要。 -### Source Maps $#source-maps$ +### source map $#source-maps$ -source map 相当消耗资源。你真的需要它们? +source map 相当消耗资源,请确保真的需要它们。 --- @@ -244,7 +245,7 @@ source map 相当消耗资源。你真的需要它们? 下列工具存在某些可能会降低构建性能的问题: -### Babel $#babel$ +### babel $#babel$ - 最小化项目中的 preset/plugin 数量。 @@ -252,8 +253,8 @@ source map 相当消耗资源。你真的需要它们? - 在单独的进程中使用 `fork-ts-checker-webpack-plugin` 进行类型检查。 - 配置 loader 跳过类型检查。 -- 使用 `ts-loader` 时,设置 `happyPackMode: true` / `transpileOnly: true`。 +- 使用 `ts-loader` 时,设置 `happyPackMode: true` 或 `transpileOnly: true`。 -### Sass $#sass$ +### sass $#sass$ -- `node-sass` 中有个来自 Node.js 线程池的阻塞线程的 bug。 当使用 `thread-loader` 时,需要设置 `workerParallelJobs: 2`。 +- `node-sass` 中存在 bug,会阻塞 Node.js 线程池中的线程。当使用 `thread-loader` 时,需要设置 `workerParallelJobs: 2`。