Last active
April 12, 2020 18:50
-
-
Save SilentImp/83374b842637fc5e0821c0d9623dc8e7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
// Count of measurements we want to make | |
const MEASURES_COUNT = 3; | |
// 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, | |
}; | |
}; | |
/** | |
* Reducer which will calculate an avarage value of all page measurements | |
* @param pages {Object} — accumulator | |
* @param page {Object} — page | |
* @param page {Object} — page with avarage metrics values | |
*/ | |
const mergeMetrics = (pages, page) => { | |
if (!pages) return page; | |
return { | |
subject: pages.subject, | |
metrics: pages.metrics.map((measure, index) => { | |
let value = (measure.value + page.metrics[index].value)/2; | |
value = +value.toFixed(2); | |
return { | |
...measure, | |
value, | |
} | |
}), | |
} | |
} | |
/** | |
* 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) { | |
// Let's measure MEASURES_COUNT times and calculate the avarage | |
let measures = []; | |
let index = MEASURES_COUNT; | |
while(index--){ | |
const metric = await builder(url); | |
measures.push(metric); | |
} | |
const measure = measures.reduce(mergeMetrics); | |
report.push(measure); | |
} | |
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