先给结论(非常重要):
PM2 ≠ 性能工具
PM2 = 运维工具
PM2 几乎不会让你的爬虫更快。
但 PM2 用错,会让你更慢、更不稳定。
1. PM2 vs node:为什么几乎没性能差异?
下面两种启动方式:
node pull-manager.js
pm2 start pull-manager.js
对性能影响几乎可以忽略,因为:
-
同一个 V8 引擎
-
同一个 event loop
-
同一份 JS 代码逻辑
PM2 提供的是:
-
✅ 守护进程 / 崩溃自动重启
-
✅ 日志管理 / 监控
-
✅ 部署 / 多环境管理
而不是:
- ❌ 让 Playwright 跑得更快
2. PM2 cluster 能提速吗?
对 Playwright 爬虫来说:
❌ 基本不会,甚至会更慢更抖。
原因只有一句话:
Playwright 是“网络 + Chromium”主导的任务,不是 CPU 主导的任务。
原因 1:Playwright 大量时间是在等网络
爬虫任务的时间构成大概是:
-
等页面资源下载
-
等接口响应
-
等 JS 渲染
-
等跳转 / 重定向
-
等 iframe / subresource
你开更多 Node 进程,只会发生一件事:
同时在等更多网络请求,并不会让单个任务变快。
原因 2:带宽是硬上限(最常被忽略)
比如你只有 4M 带宽:
-
开 1 个进程:4M → 100%
-
开 4 个进程:每个 ≈ 1M,还会叠加上下文切换 + jitter(抖动)
最终效果:
单个页面加载更慢、超时更多、失败率更高,整体吞吐反而更差。
原因 3:Chromium 多实例会互相干扰
Playwright 的 Chromium 本身非常吃资源:
-
CPU
-
fd / socket 连接数
-
突发带宽(burst)
-
内存
你 cluster 起来,多个 Chromium 同时抢资源,轻则慢,重则崩。
所以对 Playwright 爬虫来说,cluster 很多时候是“性能幻觉”。
3. 真正的提速点:优化 Playwright,而不是 PM2
如果你真要提升性能,核心在两件事:
- 最大限度削减网络负载(最值钱)
- 减少 Browser 生命周期(稳定 + 性能)
3.1 直接 abort 掉图片 / 字体 / 视频(核心)
await page.route("**/*", (route) => {
const type = route.request().resourceType();
if (["image", "media", "font"].includes(type)) {
return route.abort();
}
route.continue();
});
效果非常直接:
- 页面加载请求量减少
- 带宽大幅下降
- 渲染速度明显提升
- 并发能力上升
3.2 不要等 networkidle(常见误区)
很多人写:
await page.goto(url, { waitUntil: "networkidle" });
但现代网站(websocket / 长连接 / analytics / 广告请求)可能永远不会 idle。
建议改成:
await page.goto(url, { waitUntil: "domcontentloaded" });
await page.waitForSelector("#content");
3.3 不要滥用 screenshot / pdf(超级耗时)
截图会触发:
-
layout 计算
-
rasterize
-
额外内存占用
如果不是必要产物,强烈建议去掉。
4. 减少 Browser 生命周期(稳定 + 性能)
for (...) {
const browser = await chromium.launch();
const page = await browser.newPage();
...
await browser.close();
}
const browser = await chromium.launch();
for (const url of urls) {
const page = await browser.newPage();
await page.goto(url, { waitUntil: "domcontentloaded" });
// crawl ...
await page.close();
}
await browser.close();
结尾:一句话总结
PM2 解决的是“进程管理”,不是“性能优化”。
真正的性能提升永远发生在:网络负载 + 浏览器生命周期。