我在Puppeteer的帮助下编写了一个小型爬虫。现在,我面临的挑战是我的测试速度相当慢(每个测试> 3秒)。我已经能够追踪到Puppeteer and的launch
功能,使用Istanbul / nyc。
mocha
运行测试,则测试将在400毫秒内完成。 nyc
,则测试持续时间超过3000毫秒我正在使用的是
'use strict';
const puppeteer = require('puppeteer');
module.exports = async function startBrowser() {
const options = {
args: [
// '--no-sandbox',
// '--disable-setuid-sandbox',
// '--disable-dev-shm-usage',
// '--disable-accelerated-2d-canvas',
// '--disable-gpu'
],
headless: false // true
};
return await puppeteer.launch(options);
};
这是我正在使用的测试:
'use strict';
/* global describe: false, before: false, it: false,
beforeEach: false, afterEach: false, after: false, window: false, document: false */
const assert = require('assert').strict;
const startBrowser = require('../');
const util = require('util');
describe('Puppeteer', function() {
let pageManager;
it('start the browser', async function() {
this.timeout(10000);
console.time('startBrowser');
const browser = await startBrowser();
console.timeEnd('startBrowser');
assert(browser);
console.time('closeBrowser');
await browser.close();
console.timeEnd('closeBrowser');
});
});
我已经使用此代码创建了一个存储库并测试here。nyc _mocha ./test/*.test.js
的运行时间约为3500ms,mocha ./test/*.test.js
的运行时间仅为130ms。
到目前为止我已经尝试过:
headless: true
我该怎么做才能使覆盖范围的测试与单独进行的测试一样快?
使用中:
我已经开始调试Puppeteer,这些是我的发现:
child_process.spawn()
生成了新的浏览器nyc
正在将spawn-wrap
用于此类子进程spawn-wrap
正在使用./node_modules/puppeteer/.local-chromium/linux-686378/chrome-linux/chrome
将整个可执行文件(fs.readFileSync
)读入内存,这需要花费很长的时间才能完成spawn-wrap
的自述文件提供了某种解释:
初始wrap调用使用同步I / O。无论如何,您可能不应该在任何生产环境中使用此脚本。另外,这会大大降低子进程的执行速度,因为我们添加了一些间接层。
对我个人而言,答案是,只要使用nyc
/ istanbul
,无论是否进行代码覆盖,我在运行测试时都无法获得相同的性能。
我给了c8
一个镜头,性能几乎相同,并且我仍然可以覆盖代码。
'use strict'
const puppeteer = require('puppeteer')
module.exports = async function startBrowser() {
const options = {
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--no-first-run',
'--no-zygote',
'--single-process', // <- this one doesn't works in Windows
'--disable-gpu'
],
headless: true
}
return await puppeteer.launch(options)
}