调试

1. console.log(最常用)

console.log('value:', value);
console.error('error:', err);
console.table(arrayOfObjects);            // 表格视图
console.dir(obj, { depth: 5 });           // 深度展开
console.trace();                           // 打印调用栈
console.time('op'); /* ... */ console.timeEnd('op');    // 计时

2. node --inspect(专业)

node --inspect src/index.js
node --inspect-brk src/index.js           # 启动就断点(等调试器)

打开 Chrome → chrome://inspect → 选你的 Node 进程 → 进 DevTools 调试。

或 VS Code 配 launch.json:

{
  "type": "node",
  "request": "launch",
  "name": "Debug",
  "program": "${workspaceFolder}/src/index.ts",
  "runtimeExecutable": "tsx",
  "skipFiles": ["<node_internals>/**"]
}

按 F5 启动 + 自动接 debugger。

3. debugger 关键字

function buggy(x) {
    debugger;                             // 跑到这停
    return x * 2;
}

node --inspect 才生效。

4. ndb(更友好的 DevTools 调试器)

npm install -g ndb
ndb src/index.js

看进程

// 内存
console.log(process.memoryUsage());
// { rss, heapTotal, heapUsed, external, arrayBuffers }

// CPU 时间
const start = process.cpuUsage();
// ... 跑一段代码
console.log(process.cpuUsage(start));
// { user: microseconds, system: microseconds }

// 事件循环延迟
import { monitorEventLoopDelay } from 'perf_hooks';
const h = monitorEventLoopDelay();
h.enable();
setInterval(() => {
    console.log('Loop delay ns:', h.mean);
    h.reset();
}, 5000);

内存泄漏排查

# 1. 启动 inspector
node --inspect src/index.js

# 2. Chrome DevTools → Memory → "Take snapshot"
# 3. 让程序跑一段(产生泄漏)
# 4. 再 snapshot
# 5. Compare 两个 snapshot → 看哪些对象数量异常增长

或脚本化抓 heap dump:

import { writeHeapSnapshot } from 'v8';

setInterval(() => {
    const file = `heap-${Date.now()}.heapsnapshot`;
    writeHeapSnapshot(file);
    console.log(`Snapshot: ${file}`);
}, 60_000);

性能分析

clinic.js(全套工具)

npm install -g clinic

Doctor:综合诊断

clinic doctor -- node src/index.js
# 用 autocannon 打负载之后会自动出报告:CPU / Memory / Event Loop / I/O 哪个是瓶颈

Flame:火焰图

clinic flame -- node src/index.js
# 报告显示函数耗时占比 → 找慢函数

Bubbleprof:异步图

clinic bubbleprof -- node src/index.js
# 看哪些异步操作慢

0x(轻量火焰图)

npm install -g 0x
0x src/index.js
# 完事自动开浏览器看火焰图

benchmark:精确测时

npm install -D mitata
import { bench, run } from 'mitata';

bench('JSON.parse', () => {
    JSON.parse('{"a":1,"b":2,"c":3}');
});

bench('manual parse', () => {
    // 别的方案
});

await run();

或用 hyperfine(外部 CLI):

hyperfine 'node script.js' 'bun script.js'    # 自动多次跑统计

性能优化清单

CPU 密集

  • 拆任务(不要长同步循环)
  • worker_threads(24-worker-threads)
  • C++ 原生模块 / WASM

IO 密集

  • 用 stream(不要 readFile 大文件)
  • 并行(Promise.all)
  • 缓存(Redis)
  • 连接池

启动慢

  • 减少同步 require / import
  • 用 esbuild bundle
  • ESM dynamic import 延迟加载

内存高

  • heap snapshot 看泄漏
  • 减少缓存(LRU)
  • --max-old-space-size=N 调 V8 堆上限(MB)
  • 频繁创建 Buffer 用 Buffer.allocUnsafe + 复用

看模块加载耗时

node --inspect-brk src/index.js
# DevTools → Profiler → 启动时录制
# 看哪些 require 慢

或:

require('require-stats').start();
require('./big-module');
// 报告每个 require 多久

实战:常见慢点

现象 可能原因
QPS 上不去 event loop 被阻塞(同步代码 / CPU 密集)
内存稳定增长 泄漏(闭包 / 监听器没移除 / 缓存无限增长)
偶尔慢 GC 暂停 / IO 等待 / 上游慢
启动慢 require 多 / 同步 IO
响应忽快忽慢 event loop lag / 队列堆积

  • console.log 异步 buffered——程序立刻退出可能丢日志
  • 内存泄漏在 dev 环境看不出——只有跑长时间才暴露
  • 别上来就上 worker / cluster——先 profile 看真瓶颈
  • --prof + 分析报告麻烦——0x / clinic 更友好

下一篇:部署。