使用puppeteer创建pdf的最佳做法是什么?

时间:2019-03-03 02:30:51

标签: node.js docker pdf puppeteer

我正在使用puppeteer从HTML模板创建pdf。以下两种解决方案中的最佳做法是哪种方法?

1。始终启动puppeteer并创建一个新的浏览器来创建pdf。创建完pdf后,浏览器关闭

(async () => {
  const finalHtml = 'html content...';
  const browser = await puppeteer.launch();
  const page = await browser.pages()[0];
  await page.setContent(finalHtml);
  await page.pdf({path: 'hn.pdf', format: 'A4'});

  await browser.close();
})();

2。保留1个实例浏览器。始终创建一个新的页面来创建pdf。完成创建pdf后,页面关闭

const browser = await puppeteer.launch();

(async () => {
  const finalHtml = 'html content...';
  const page = await browser.newPage();
  await page.setContent(finalHtml);
  await page.pdf({path: 'hn.pdf', format: 'A4'});
  await page.close();
})();

谢谢。

编辑1:另外,上述两种解决方案的优缺点是什么?

1 个答案:

答案 0 :(得分:5)

短寿命浏览器(每次打开新的浏览器实例)

优点:

  • 每次打开一个新会话时,一个实例不会干扰另一个实例。
  • 完美地测试同一/多个网站上的多个凭据。
  • 可以使用实例范围的代理。

缺点:

  • 您不能轻松地在两个实例之间共享数据(除非您使用userDataDircookies)。
  • 需要更多时间才能打开。

寿命长的浏览器(每次共享相同的浏览器实例)

优点:

  • 打开新标签页所花的时间比打开带有空配置文件的新镶边要少。
  • 在两个实例之间轻松共享数据。完美地抓取/测试具有相同凭据的相同网站。

缺点:

  • 您将无法使用不同的凭据在同一网站上使用身份验证和cookie。
  • 不能使用实例范围的代理(在此菜单中)。

基准

这里是仅运行100次的基准。

要运行的代码:

const bench = require("@entrptaher/async-bench");
const puppeteer = require("puppeteer");

const createNewBrowser = async function() {
  const finalHtml = "html content...";
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(finalHtml);
  await page.pdf({ path: "hn_shortlived.pdf", format: "A4" });
  await browser.close();
  return true;
};

let longLivedBrowser;
const useExisting = async function() {
  const finalHtml = "html content...";
  if (!longLivedBrowser) {
    longLivedBrowser = await puppeteer.launch();
  }
  const page = await longLivedBrowser.newPage();
  await page.setContent(finalHtml);
  await page.pdf({ path: "hn_longlived.pdf", format: "A4" });
  await page.close();
  return true
};

let longLivedNoNewTab;
const useExitingTab = async function() {
  const finalHtml = "html content...";
  if (!longLivedNoNewTab) {
    longLivedNoNewTab = await puppeteer.launch();
  }
  const page = (await longLivedNoNewTab.pages())[0];
  await page.setContent(finalHtml);
  await page.pdf({ path: "hn_longlived.pdf", format: "A4" });
  return true
};

const times = 100;

Promise.all([
  bench(createNewBrowser, times),
  bench(useExisting, times),
  bench(useExitingTab, times)
]).then(console.log);

结果:

[ { meanExecTime: 277.3644104500115,
    execTime: 27736.44104500115,
    resultOfMethod: true },
  { meanExecTime: 36.89182792000472,
    execTime: 3689.1827920004725,
    resultOfMethod: true },
  { meanExecTime: 11.07780257999897,
    execTime: 1107.780257999897,
    resultOfMethod: true } ]

每个都有以下内容:

  • meanExecTime:平均运行时间
  • execTime:总运行时间
  • resultOfMethod:仅用于识别的结果

该基准是不完整的,因为它没有机器详细信息等。但是它绝对表明,每次打开浏览器都将花费更多时间,即使只有100次。

在第二个功能上,您还将注意到打开新标签页需要花费时间,因此在第三个功能上,如果不关闭页面,则将花费更少的时间。

摘要:

  • 如果您需要性能(11ms,而277ms),则不关心会话,请选择现有标签。
  • 如果要在同一窗口上并行运行多个测试,请转到新选项卡。
  • 如果您需要会话和持久性,请使用新的浏览器实例。
相关问题