主题
性能分析工具
性能分析
必要先聊聊:如何收集、分析 Webpack 打包过程的性能数据。
收集数据的方法很简单 —— Webpack 内置了 stats 接口,专门用于统计模块构建耗时、模块依赖关系等信息,推荐用法:
- 在
webpack.config.js
中添加配置
js
module.exports = {
profile: true
}
- 编译命令中添加
--json
参数,参数值为最终生成的统计文件名
shell
webpack --json=stats.json
上述命令执行完毕后,会在文件夹下生成 stats.json
文件,内容大致如下:
json
{
"hash": "2c0b66247db00e494ab8",
"version": "5.36.1",
"time": 81,
"builtAt": 1620401092814,
"publicPath": "",
"outputPath": "/Users/tecvan/learn-webpack/hello-world/dist",
"assetsByChunkName": { "main": ["index.js"] },
"assets": [
// ...
],
"chunks": [
// ...
],
"modules": [
// ...
],
"entrypoints": {
// ...
},
"namedChunkGroups": {
// ...
},
"errors": [
// ...
],
"errorsCount": 0,
"warnings": [
// ...
],
"warningsCount": 0,
"children": [
// ...
]
}
stats
对象收集了 Webpack 运行过程中许多值得关注的信息,包括:
modules
:本次打包处理的所有模块列表,内容包含模块的大小、所属chunk
、构建原因、依赖模块等,特别是modules.profile
属性,包含了构建该模块时,解析路径、编译、打包、子模块打包等各个环节所花费的时间,非常有用;chunks
:构建过程生成的chunks
列表,数组内容包含chunk
名称、大小、包含了哪些模块等;assets
:编译后最终输出的产物列表、文件路径、文件大小等;entrypoints
:entry 列表,包括动态引入所生产的 entry 项也会包含在这里面;children
:子 Compiler 对象的性能数据,例如extract-css-chunk-plugin
插件内部就会调用函数创建出子 Compiler 来做 CSS 抽取的工作。
我们可以从这些数据中分析出模块之间的依赖关系、体积占比、编译构建耗时等,Webpack 社区还提供了许多优秀的分析工具,能够将这些数据转换各种风格的可视化图表,帮助我们更高效地找出性能卡点
Webpack Analysis
Webpack Analysis 是 webpack 官方提供的可视化分析工具,相比于其它工具,它提供的视图更全,功能更强大,能够通过创建依赖关系图对你的包进行更彻底的检查。
使用生成的 stats.json
文件导入页面,就可以看到一些关键统计信息:
Webpack Bundle Analyzer
Webpack-bundle-analyzer 是一个非常有名的性能分析插件,只需要一些简单配置就可以在 Webpack 构建结束后生成 Tree Map 形态的模块分布统计图,用户可以通过对比 Tree Map 内容推断各模块的体积占比,是否包含重复模块、不必要的模块等,用法:
- 安装依赖
shell
npm i -D webpack-bundle-analyzer
- 添加配置
js
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin
module.exports = {
...
plugins: [new BundleAnalyzerPlugin()],
}
Speed Measure Plugin
SpeedMeasureWebpackPlugin 插件能够统计出各个 Loader、插件的处理耗时,开发者可以根据这些数据分析出哪些类型的文件处理更耗时间,用法:
- 安装依赖
shell
npm i -D speed-measure-webpack-plugin
- 配置
js
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin")
const smp = new SpeedMeasurePlugin()
const config = {
entry: "./src/index.ts",
// ...
}
// 注意,这里是用 `smp.wrap` 函数包裹住 Webpack 配置
module.exports = smp.wrap(config)