NodeJs-Performance Hooks

 后端   小卒子   2024-09-06 10:15   119
  nodejs

Node.jsPerformance Hooks 模块允许开发者通过监控性能测量来分析和优化代码。这一模块提供了与性能相关的 API,用于创建时间戳、度量程序执行时间,并提供精确的时间度量。开发者可以使用这些工具来优化应用性能,追踪瓶颈或检查性能基准。

本文将详细介绍 Performance Hooks 模块的所有属性、方法及其使用方式,涵盖文档的所有内容。

1. 模块引入

Performance Hooks 是 Node.js 的内置模块之一,可以通过以下方式引入:

const { performance, PerformanceObserver } = require('perf_hooks');

2. 核心概念

Performance Hooks 模块基于 W3C Performance Timeline API 的规范,允许开发者测量代码性能,记录标记和度量来分析程序执行的时长。

  • 时间源 (timeOrigin): 是从 Node.js 进程启动到 performance.now() 的时间点,提供相对时间戳,精度达到毫秒级别。
  • 标记 (marks): 是性能时间轴上的标签,用于度量事件发生时的时间。
  • 度量 (measures): 用于计算不同标记之间的时间差。

3. 性能测量 API

3.1 performance.now()

performance.now() 返回从 Node.js 进程启动到当前调用时间的毫秒数(相对时间戳),其精度达到小数点后三位(微秒级别)。

const startTime = performance.now();
// 执行一些代码
const endTime = performance.now();
console.log(`操作耗时 ${endTime - startTime} 毫秒`);

3.2 performance.timeOrigin

performance.timeOrigin 返回 Node.js 进程启动时的 UNIX 时间戳。可以用于与 performance.now() 结合计算绝对时间。

console.log(performance.timeOrigin);  // 输出:进程启动时的 UNIX 时间戳

3.3 performance.mark()

performance.mark() 用于在性能时间线上创建一个标记。可以使用多个标记来度量代码执行的时长。

performance.mark('start');

// 执行一些代码

performance.mark('end');

3.4 performance.measure()

performance.measure() 用于计算两个标记之间的时间,并创建一个 PerformanceEntry 对象。你需要传入度量名称以及开始和结束标记名称。

performance.mark('start');
// 执行一些代码
performance.mark('end');

performance.measure('测量从 start 到 end 的时间', 'start', 'end');

这个方法会生成一个新的 PerformanceEntry,并存储度量的结果。

3.5 performance.clearMarks()

performance.clearMarks() 清除一个或多个标记。如果未提供参数,则清除所有标记。

performance.clearMarks('start');
performance.clearMarks();  // 清除所有标记

3.6 performance.clearMeasures()

performance.clearMeasures() 清除一个或多个测量。如果未提供参数,则清除所有测量。

performance.clearMeasures('测量名称');
performance.clearMeasures();  // 清除所有测量

4. 性能观察者 API

性能观察者 (PerformanceObserver) 允许你监控并响应性能条目的生成事件。使用 PerformanceObserver,你可以监听如 markmeasure 等性能条目的创建,并在条目创建时执行自定义代码。

4.1 PerformanceObserver

PerformanceObserver 是一个监听性能条目生成的观察者。通过该观察者,你可以处理特定类型的性能条目。

创建一个 PerformanceObserver

const observer = new PerformanceObserver((items) => {
  items.getEntries().forEach((entry) => {
    console.log(`名称: ${entry.name}, 类型: ${entry.entryType}, 开始时间: ${entry.startTime}, 持续时间: ${entry.duration}`);
  });
});

observer.observe({ entryTypes: ['measure'] });

上面的代码会监听所有 measure 类型的性能条目,并在它们生成时输出相应信息。

observe() 方法

observe() 方法用于指定要监听的性能条目类型。可以监听多种类型的条目,例如 markmeasuregc(垃圾回收)等。

observer.observe({ entryTypes: ['mark', 'measure'] });

disconnect() 方法

disconnect() 用于停止性能观察者的监听。

observer.disconnect();

5. 性能条目类型

性能条目对象提供关于性能事件的信息。以下是常见的性能条目类型。

5.1 PerformanceEntry

PerformanceEntry 对象包含性能事件的详细信息,包括:

  • name: 条目名称
  • entryType: 条目的类型,如 markmeasure
  • startTime: 条目开始时间(以毫秒为单位)
  • duration: 条目的持续时间(仅适用于 measure

示例:

const observer = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  entries.forEach((entry) => {
    console.log(entry.name, entry.startTime, entry.duration);
  });
});
observer.observe({ entryTypes: ['mark', 'measure'] });

6. 使用示例

示例 1: 测量代码块的执行时间

const { performance } = require('perf_hooks');

performance.mark('start');

// 执行一些操作
for (let i = 0; i < 1000000; i++) {}

performance.mark('end');
performance.measure('for 循环执行时间', 'start', 'end');

const entries = performance.getEntriesByType('measure');
entries.forEach((entry) => {
  console.log(`${entry.name}: ${entry.duration}ms`);
});

示例 2: 监听性能条目

const { performance, PerformanceObserver } = require('perf_hooks');

const obs = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  entries.forEach((entry) => {
    console.log(`条目: ${entry.name}, 开始时间: ${entry.startTime}, 持续时间: ${entry.duration}`);
  });
});
obs.observe({ entryTypes: ['measure'] });

performance.mark('startTask');

// 执行任务
for (let i = 0; i < 1000000; i++) {}

performance.mark('endTask');
performance.measure('任务执行时间', 'startTask', 'endTask');

7. 总结

Node.jsPerformance Hooks 模块为开发者提供了强大的性能监测工具,可以帮助追踪代码中的性能瓶颈和执行时长。通过标记和测量,开发者可以轻松记录关键代码的性能数据,并使用 PerformanceObserver 监听和处理这些性能事件。