0%

NodeJs性能分析

NodeJs性能分析

这里提出一种面向NodeJs的基于Chrome Dev Tools的性能分析方法。

核心思路

  • 基于console.profile记录性能描述信息,输出.cpuprofile文件。
  • 基于Inspector记录内存占用信息, 输出.heapsnapshot文件。
  • 基于Chrome读取.cpuprofile.heapsnapshot文件分析性能问题。

效果

JS执行情况

image-20240111175431182

内存占用情况

image-20240111175943820

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import * as inspector from "inspector"
import * as path from "path";
import * as fs from "fs"
export class Profile {
label: string
private profileFilePath: string
private session: inspector.Session;
private heapsnapshotFileId: number;
private labelComplete: string;
constructor(label: string) {
this.label = label
this.profileFilePath = path.resolve(__dirname, "../") + '/';
}
starGetCpuProfile() {
console.profile(this.label + `-${this.labelComplete}`);
}
endGetCpuProfile() {
console.profileEnd(this.label + `-${this.labelComplete}`);
}
startGetHeapsnapshot() {
this.session = new inspector.Session();
this.heapsnapshotFileId = fs.openSync(this.profileFilePath + this.label + `-${this.labelComplete}` + '.heapsnapshot', 'w');
this.session.connect();
this.session.on('HeapProfiler.addHeapSnapshotChunk', (m) => {
fs.writeSync(this.heapsnapshotFileId, m.params.chunk);
});
}
endGetHeapsnapshot() {
this.session.post('HeapProfiler.takeHeapSnapshot', null, (err, r) => {
this.session.disconnect();
fs.closeSync(this.heapsnapshotFileId);
});
}
start() {
const now = new Date();
this.labelComplete = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}-${now.getHours().toString().padStart(2, '0')}-${now.getMinutes().toString().padStart(2, '0')}-${now.getSeconds().toString().padStart(2, '0')}`
// fist start get heapsnapshot
this.startGetHeapsnapshot();
this.starGetCpuProfile();
}
end() {
// fist end get cpu profile
this.endGetCpuProfile();
this.endGetHeapsnapshot();
}
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { Profile } from "profile"
const getDependencyTreeProfile = new Profile('getDependencyTree');
// 开始记录性能信息
getDependencyTreeProfile.start()
let dependencyTreeData = undefined;
try {
// 一些比较耗性能的工作 这里以获取文件的依赖关系为例
dependencyTreeData = getDependencyTree(
path.join(folderPath, mainFilePath),
folderPath,
{
alias,
resolveExtensions,
onGotFileString,
onGotAST,
onGotCircularStructureNode,
});
} catch (e) {
// 性能信息记录结束
getDependencyTreeProfile.end()
return false;
}
// 性能信息记录结束
getDependencyTreeProfile.end()