puppeteer.launch() 与 puppeteer.connect() 的性能差异是什么?

What's the performance difference of puppeteer.launch() versus puppeteer.connect()?

我目前正在使用包装 puppeteer 的 svg 转换库:
https://github.com/etienne-martin/svg-to-img

每次调用其转换函数后,它会等待 500 毫秒,如果没有任何其他调用,则会关闭浏览器实例,并在后续调用中再次调用 puppeteer.launch

我在 Kubernetes 集群的 docker 容器 运行 中使用它。我想知道连续调用 puppeteer.launch 与连接到一个已经 运行 的无头实例 chrome.

相比,成本有多高

我正在考虑总是有一个 docker 容器 运行 无头实例 chrome 并从我的 docker 容器连接到它进行 svg 转换.

虽然我想了解一下 launchconnect 幕后发生的事情,但在执行此操作之前。

简答:

从性能的角度来看,尽可能使用 puppeteer.connect() / browser.disconnect() 是最好的,并且 ≈ 146 倍 比使用 puppeteer.launch() / browser.close()(根据我的基准测试)。

详细答案:

我运行一些测试来比较调用puppeteer.connect() / browser.disconnect() versus puppeteer.launch() / browser.close()的性能。

每个方法测试10000次,记录所有迭代的总时间和每次迭代的平均时间。

我的测试发现使用 puppeteer.connect() / browser.disconnect() 比使用 puppeteer.launch() / browser.close()146 倍

您可以使用下面提供的代码在您自己的机器上执行测试。

基准 (puppeteer.launch() / browser.close()):

'use strict';

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

const iterations = 10000;

(async () => {
  let browser;
  
  const start_time = performance.now();
  
  for (let i = 0; i < iterations; i++) {
      browser = await puppeteer.launch();
      
      await browser.close();
  }
  
  const end_time = performance.now();
  
  const total_time = end_time - start_time;
  const average_time = total_time / iterations;
  
  process.stdout.write (
      'Total Time:\t' + total_time + ' ms\n'
    + 'Average Time:\t' + average_time + ' ms\n'
    + 'Iterations:\t' + iterations.toLocaleString() + '\n'
  );
})();

结果:

Total Time: 1339075.0866550002 ms

Average Time: 133.90750866550002 ms

Iterations: 10,000


基准 (puppeteer.connect() / browser.disconnect()):

'use strict';

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

const iterations = 10000;

(async () => {
  let browser = await puppeteer.launch();
  const browserWSEndpoint = browser.wsEndpoint();
  
  browser.disconnect();
  
  const start_time = performance.now();
  
  for (let i = 0; i < iterations; i++) {
    browser = await puppeteer.connect({
      browserWSEndpoint,
    });
    
    browser.disconnect();
  }
  
  const end_time = performance.now();
  
  const total_time = end_time - start_time;
  const average_time = total_time / iterations;
  
  process.stdout.write (
      'Total Time:\t' + total_time + ' ms\n'
    + 'Average Time:\t' + average_time + ' ms\n'
    + 'Iterations:\t' + iterations.toLocaleString() + '\n'
  );
  
  process.exit();
})();

结果:

Total Time: 9198.328596000094 ms

Average Time: 0.9198328596000094 ms

Iterations: 10,000


Puppeteer 源代码:

您可以通过检查相关函数的源代码来查看幕后发生的事情:

puppeteer.launch()

puppeteer.launch() 启动 chromium 实例并随后连接到它。 Chromium 实例的启动需要 100 到 150 毫秒,具体取决于您的硬件。连接立即发生(因为它是本地计算机上的 websocket)。

puppeteer.connect()

puppeteer.connect() 仅连接到现有的 Chromium 实例。

  • 如果您要连接的实例与您的脚本是同一台机器,这应该像以前一样立即发生(<1ms)。
  • 如果您 运行 第二台机器上的 chromium 实例,您将为 puppeteer.connect() 调用和 所有后续的 puppeteer 函数调用引入网络延迟 .延迟将完全取决于网络,但如果您的机器位于同一位置,则延迟应低于 10 毫秒。

svg 转 img

关于您链接的库:您链接的库似乎不支持连接到 puppeteer 实例。您还可以将库放在机器上并提供一个 API 来接收 SVG 代码和 returns 图像。这样你就可以保留 chromium 实例 运行ning.