使用 puppeteer 创建 pdf 的最佳实践是什么?
Which is the best practice using puppeteer to create pdf?
我正在使用 puppeteer 从 HTML 模板创建 pdf。以下两种解决方案中哪种方法是最佳做法?
1.Always 启动 puppeteer 并创建一个新的 browser 来创建 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.Keep 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:另外,以上两种方案的优缺点是什么?
短暂的浏览器(每次打开新的浏览器实例)
优点:
- 每次打开一个新会话,一个实例不会干扰另一个实例。
- 非常适合在 same/multiple 网站上测试多个凭据。
- 可以使用实例级代理。
缺点:
- 您不能轻易地在两个实例之间共享数据(除非您使用
userDataDir
或 cookies
)。
- 打开需要更多时间。
长寿命浏览器(每次共享相同的浏览器实例)
优点:
- 打开一个新标签比打开一个新的 chrome 使用空配置文件花费的时间更少。
- 数据很容易在两个实例之间共享。非常适合 scraping/testing 具有相同凭据的相同网站。
缺点:
- 您将无法使用不同的凭据在同一网站上使用身份验证和 cookie。
- 无法使用实例范围的代理(此时)。
基准
这里是 运行ning 仅 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 次。
在第二个功能上,你也会注意到打开一个新标签需要时间,所以在第三个功能上如果你不关闭页面,它会花费更少的时间。
总结:
- 如果您需要性能(11 毫秒与 277 毫秒相比),请不要关心会话,使用现有选项卡。
- 如果您想 运行 对同一个 window 并行进行多项测试,请选择新标签。
- 如果您需要会话和持久性,请使用新的浏览器实例。
我正在使用 puppeteer 从 HTML 模板创建 pdf。以下两种解决方案中哪种方法是最佳做法?
1.Always 启动 puppeteer 并创建一个新的 browser 来创建 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.Keep 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:另外,以上两种方案的优缺点是什么?
短暂的浏览器(每次打开新的浏览器实例)
优点:
- 每次打开一个新会话,一个实例不会干扰另一个实例。
- 非常适合在 same/multiple 网站上测试多个凭据。
- 可以使用实例级代理。
缺点:
- 您不能轻易地在两个实例之间共享数据(除非您使用
userDataDir
或cookies
)。 - 打开需要更多时间。
长寿命浏览器(每次共享相同的浏览器实例)
优点:
- 打开一个新标签比打开一个新的 chrome 使用空配置文件花费的时间更少。
- 数据很容易在两个实例之间共享。非常适合 scraping/testing 具有相同凭据的相同网站。
缺点:
- 您将无法使用不同的凭据在同一网站上使用身份验证和 cookie。
- 无法使用实例范围的代理(此时)。
基准
这里是 运行ning 仅 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 次。
在第二个功能上,你也会注意到打开一个新标签需要时间,所以在第三个功能上如果你不关闭页面,它会花费更少的时间。
总结:
- 如果您需要性能(11 毫秒与 277 毫秒相比),请不要关心会话,使用现有选项卡。
- 如果您想 运行 对同一个 window 并行进行多项测试,请选择新标签。
- 如果您需要会话和持久性,请使用新的浏览器实例。