Skip to content

Instantly share code, notes, and snippets.

@SilentImp SilentImp/cluster.js
Last active Apr 12, 2020

Embed
What would you like to do?
const fs = require('fs');
const lighthouse = require('lighthouse');
const puppeteer = require('puppeteer');
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
const DOMAIN = process.env.DOMAIN;
// build report for single url
const buildReport = browser => async url => {
const data = await lighthouse(
`${DOMAIN}${url}`,
{
port: new URL(browser.wsEndpoint()).port,
output: 'json',
},
{
extends: 'lighthouse:full',
}
);
const { report: reportJSON } = data;
const report = JSON.parse(reportJSON);
const metrics = [
{
name: report.categories.performance.title,
value: report.categories.performance.score,
desiredSize: 'larger',
},
{
name: report.categories.accessibility.title,
value: report.categories.accessibility.score,
desiredSize: 'larger',
},
{
name: report.categories['best-practices'].title,
value: report.categories['best-practices'].score,
desiredSize: 'larger',
},
{
name: report.categories.seo.title,
value: report.categories.seo.score,
desiredSize: 'larger',
},
{
name: report.categories.pwa.title,
value: report.categories.pwa.score,
desiredSize: 'larger',
},
];
return {
subject: url,
metrics: metrics,
};
};
/**
* Returns urls array splited to chunks accordin to cors number
*
* @param urls {String[]} — URLs array
* @param cors {Number} — count of available cors
* @return {Array<String[]>} — URLs array splited to chunks
*/
function chunkArray(urls, cors) {
const chunks = [...Array(cors)].map(() => []);
let index = 0;
urls.forEach((url) => {
if (index > (chunks.length - 1)) {
index = 0;
}
chunks[index].push(url);
index += 1;
});
return chunks;
}
const urls = [
'/inloggen',
'/wachtwoord-herstellen-otp',
'/lp/service',
'/send-request-to/ww-tammer',
'/post-service-request/binnenschilderwerk',
];
(async () => {
if (cluster.isMaster) {
// Parent proccess
const chunks = chunkArray(urls, numCPUs);
chunks.map(chunk => {
const worker = cluster.fork();
worker.send(chunk);
});
let report = [];
let reportsCount = 0;
cluster.on('message', (worker, msg) => {
report = [...report, ...msg];
worker.disconnect();
reportsCount++;
if (reportsCount === chunks.length) {
fs.writeFileSync(`./performance.json`, JSON.stringify(report));
process.exit(0);
}
});
} else {
// Child process
process.on('message', async (urls) => {
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox', '--headless'],
});
const builder = buildReport(browser);
const report = [];
for (let url of urls) {
const metrics = await builder(url);
report.push(metrics);
}
cluster.worker.send(report);
await browser.close();
});
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.