Skip to content
On this page

Node.js 性能优化

Node.js 以其非阻塞 I/O 和事件驱动的特性而闻名,但在处理高并发场景时,仍然需要进行性能优化。本文将介绍一些 Node.js 性能优化的最佳实践。

使用适当的版本

确保使用最新的 Node.js 版本,因为每个新版本都会带来性能改进。

优化内存使用

避免内存泄漏

  • 及时清理不再使用的变量和事件监听器
  • 使用 weakmap 存储临时数据
  • 避免在循环中创建闭包

合理设置内存限制

根据应用需求,合理设置 Node.js 的内存限制。

bash
# 设置最大内存为 4GB
NODE_OPTIONS="--max-old-space-size=4096" node app.js

优化 I/O 操作

使用异步 I/O

Node.js 的优势在于异步 I/O,确保充分利用这一特性。

javascript
// 正确的做法 - 使用异步 I/O
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) throw err
  console.log(data)
})

// 错误的做法 - 使用同步 I/O
const data = fs.readFileSync('file.txt', 'utf8')
console.log(data)

使用流处理大文件

对于大文件,使用流来处理,避免一次性加载到内存。

javascript
const fs = require('fs')
const readStream = fs.createReadStream('large-file.txt')
const writeStream = fs.createWriteStream('output.txt')

readStream.pipe(writeStream)

优化网络请求

使用连接池

对于数据库连接和 HTTP 请求,使用连接池来减少建立连接的开销。

javascript
// 使用数据库连接池
const mysql = require('mysql2/promise')

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'test',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
})

// 使用连接池执行查询
async function query(sql) {
  const [rows] = await pool.execute(sql)
  return rows
}

缓存频繁请求的数据

使用缓存来减少重复计算和数据库查询。

javascript
const NodeCache = require('node-cache')
const cache = new NodeCache({ stdTTL: 60 }) // 缓存 60 秒

async function getData(id) {
  // 先从缓存获取
  const cachedData = cache.get(`data:${id}`)
  if (cachedData) return cachedData
  
  // 缓存未命中,从数据库获取
  const data = await db.query('SELECT * FROM data WHERE id = ?', [id])
  
  // 存入缓存
  cache.set(`data:${id}`, data)
  
  return data
}

监控和分析

使用性能分析工具

  • 使用 node --inspect 启动调试模式
  • 使用 Chrome DevTools 进行性能分析
  • 使用 clinic.js 分析性能瓶颈

监控关键指标

  • CPU 使用率
  • 内存使用情况
  • 响应时间
  • 请求队列长度

通过以上优化策略,可以显著提升 Node.js 应用的性能和稳定性。