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

Dan*_*ury 4 docker puppeteer

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

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

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

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

在这样做之前,我想了解一下launchconnect的幕后发生了什么。

Gra*_*ler 11

简答:

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

详细解答:

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

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

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

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

基准 ( 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'
  );
})();
Run Code Online (Sandbox Code Playgroud)

结果

总时间:1339075.0866550002 毫秒

平均时间:133.90750866550002 毫秒

迭代次数: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();
})();
Run Code Online (Sandbox Code Playgroud)

结果

总时间:9198.328596000094 ms

平均时间:0.9198328596000094 ms

迭代次数:10,000


Puppeteer 源代码:

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

  • 在我看来,像这样比较 `connect` 和 `launch` 没有意义,因为 `launch` 基本上是“启动铬”+ `connect`。此外,“从性能角度来看,尽可能使用 puppeteer.connect() / browser.disconnect() 是最好的”建议忽略了任何网络延迟(如果 OP 的 docker 容器位于不同的机器上,这可能是相关的)。 (3认同)

Tho*_*orf 6

puppeteer.launch()

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

puppeteer.connect()

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

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

svg 到 img

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