Puppeteer无头Chrome点击事件性能过慢问题求助
Puppeteer点击操作耗时过长的优化方案
问题背景
我用Puppeteer无头Chrome开发了网页自动化代码,逻辑是定位元素并点击,但点击事件耗时极长(单次90-400ms),远低于预期,且所有元素无需滚动即可显示。相关代码及日志如下:
代码片段
logger.verbose(`before clicking on row`); // get by link text // search for any element with this class and text let workElement = await page.$x(`//span[contains(@class,"tr-class") and contains(text(),"${jobSearchId}")]`); //we don't want to click on the element itself because it makes things more difficult let row = await (await workElement.getProperty("parentNode")).getProperty("parentNode"); await row.click(); logger.verbose(`row clicked`); //click on the button logger.verbose(`button click before`); await page.click(".searchJobDescription"); logger.verbose(`button clicked`);
运行日志
0|main | 2022-08-17 13:09:05.283 - verbose: before clicking on row 0|main | 2022-08-17 13:09:05.685 - verbose: row clicked 0|main | 2022-08-17 13:09:05.685 - verbose: button click before 0|main | 2022-08-17 13:09:05.776 - verbose: button clicked
其中点击行元素耗时402ms,点击按钮耗时91ms,远慢于人类操作,需优化提速。
优化方案
1. 简化元素定位逻辑,减少跨上下文通信
当前通过$x定位元素后连续调用两次parentNode,涉及多次Node.js与Chrome的跨上下文通信,会增加耗时。可直接在XPath中定位目标行元素:
logger.verbose(`before clicking on row`); // 直接用XPath定位span的祖父节点(目标行) let row = await page.$x(`//span[contains(@class,"tr-class") and contains(text(),"${jobSearchId}")]/../../`); if (row.length > 0) { await row[0].click(); } logger.verbose(`row clicked`);
2. 跳过自动等待行为
默认情况下,page.click()和元素的click()方法会自动等待元素可见、可交互,该等待过程是耗时主要来源之一。若已确认元素无需滚动且始终可交互,可通过waitFor: false跳过等待:
// 点击行时跳过等待 await row.click({ waitFor: false }); // 点击按钮时跳过等待 await page.click(".searchJobDescription", { waitFor: false });
3. 直接在浏览器上下文执行点击
跨上下文通信是Puppeteer操作耗时的核心原因,使用page.evaluate()直接在Chrome内部执行定位和点击逻辑,减少通信开销:
logger.verbose(`before clicking on row`); // 浏览器上下文内定位并点击行 await page.evaluate((jobSearchId) => { const targetSpan = Array.from(document.querySelectorAll('span.tr-class')) .find(el => el.textContent.includes(jobSearchId)); if (targetSpan) { targetSpan.parentNode.parentNode.click(); } }, jobSearchId); logger.verbose(`row clicked`); logger.verbose(`button click before`); // 浏览器上下文内点击按钮 await page.evaluate(() => { document.querySelector(".searchJobDescription").click(); }); logger.verbose(`button clicked`);
4. 优化浏览器启动参数
启动Chrome时添加性能相关参数,减少资源消耗:
const browser = await puppeteer.launch({ headless: "new", // 新版无头模式性能更优 args: [ "--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--disable-gpu", "--no-first-run", "--no-default-browser-check", "--disable-background-networking", "--disable-background-timer-throttling", "--disable-renderer-backgrounding" ] });
内容的提问来源于stack exchange,提问作者Wazime
相关产品推荐
相关产品推荐

