
Node.js 性能分析
使用 clinic.js 进行 CPU 分析
# 安装 clinic.js
npm install -g clinic
# CPU 分析器(火焰图)
clinic flame -- node server.js
# Doctor(事件循环、内存、CPU 概览)
clinic doctor -- node server.js
# Bubbleprof(异步瓶颈)
clinic bubbleprof -- node server.js

内置 Node.js 分析器
# 启用分析启动
node --prof server.js
# 运行负载测试
npx autocannon http://localhost:3000/api/heavy -d 10
# 处理分析数据
node --prof-process isolate-0x*.log > profile.txt
# 查看火焰图
node --prof-process --preprocess isolate-0x*.log | flamebearer

内存泄漏检测
// 检测内存增长
const startMemory = process.memoryUsage();
setInterval(() => {
const mem = process.memoryUsage();
const heapGrowth = mem.heapUsed - startMemory.heapUsed;
if (heapGrowth > 100 * 1024 * 1024) { // 100MB 增长
console.warn('检测到潜在内存泄漏', {
heapUsed: Math.round(mem.heapUsed / 1024 / 1024) + 'MB',
heapTotal: Math.round(mem.heapTotal / 1024 / 1024) + 'MB',
rss: Math.round(mem.rss / 1024 / 1024) + 'MB',
});
}
}, 30000);
# 使用 node-inspector 进行堆快照
node --inspect server.js
# 打开 Chrome DevTools -> Memory -> 获取堆快照
# 比较疑似泄漏前后的快照
# 编程方式使用 heapdump
npm install heapdump
import heapdump from 'heapdump';
process.on('SIGUSR2', () => {
const filename = `/tmp/heapdump-${Date.now()}.heapsnapshot`;
heapdump.writeSnapshot(filename, (err, filename) => {
if (!err) console.log('堆快照已保存:', filename);
});
});
// 触发: kill -SIGUSR2 <pid>

事件循环监控
import { monitorEventLoopDelay } from 'perf_hooks';
const h = monitorEventLoopDelay({ resolution: 20 });
h.enable();
setInterval(() => {
const mean = h.mean / 1e6; // 转换为毫秒
const p99 = h.percentile(99) / 1e6;
if (p99 > 100) {
console.warn(`事件循环延迟高: mean=${mean.toFixed(1)}ms, p99=${p99.toFixed(1)}ms`);
}
h.reset();
}, 5000);
常见性能问题
// 问题:同步操作阻塞事件循环
import fs from 'fs';
// 不好:阻塞事件循环
const data = fs.readFileSync('/large-file.json');
// 好:非阻塞
const data = await fs.promises.readFile('/large-file.json');
// 问题:同步解析大型 JSON
// 不好:大型对象会阻塞
const parsed = JSON.parse(largeJsonString);
// 好:对大数据使用流
import { createReadStream } from 'fs';
import { createInterface } from 'readline';
const rl = createInterface({ input: createReadStream('data.ndjson') });
for await (const line of rl) {
const item = JSON.parse(line);
await processItem(item);
}
// 问题:主线程上的 CPU 密集型任务
// 使用 worker_threads 处理 CPU 工作
import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
if (!isMainThread) {
const result = heavyComputation(workerData.input);
parentPort!.postMessage(result);
}
async function runInWorker(input: unknown): Promise<unknown> {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, { workerData: { input } });
worker.on('message', resolve);
worker.on('error', reject);
});
}
使用 autocannon 进行基准测试
# 基本基准测试
npx autocannon http://localhost:3000/api/users -d 10 -c 100
# 选项:
# -d 10 持续时间 10 秒
# -c 100 100 个连接
# -p 10 10 个管道请求
# 比较优化前后
npx autocannon http://localhost:3000/api/users -d 30 -c 50 --json > before.json
# 进行优化
npx autocannon http://localhost:3000/api/users -d 30 -c 50 --json > after.json
在优化之前进行分析——大多数性能问题存在于 10% 的代码中。