Skip to content

Instantly share code, notes, and snippets.

@WebDevLuke

WebDevLuke/lh.js Secret

Last active Nov 7, 2020
Embed
What would you like to do?
Simple Google Lighthouse tool to create and compare reports from the console.
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
const argv = require('yargs').argv;
const url = require('url');
const fs = require('fs');
const glob = require('glob');
const path = require('path');
const launchChromeAndRunLighthouse = (url) => {
return chromeLauncher.launch().then(chrome => {
const opts = {
port: chrome.port
}
return lighthouse(url, opts).then(results => {
return chrome.kill().then(() => {
return {
js: results.lhr,
json: results.report
}
});
});
});
}
const getContents = (pathStr) => {
const output = fs.readFileSync(pathStr, 'utf8', (err, results) => {
return results;
});
return JSON.parse(output);
};
const compareReports = (from, to) => {
const metricFilter = [
'first-contentful-paint',
'first-meaningful-paint',
'speed-index',
'estimated-input-latency',
'total-blocking-time',
'max-potential-fid',
'time-to-first-byte',
'first-cpu-idle',
'interactive'
]
const calcPercentageDiff = (from, to) => {
const per = ((to - from) / from) * 100;
return Math.round(per * 100) / 100;
};
for(let auditObj in from['audits']) {
if(metricFilter.includes(auditObj)) {
const percentageDiff = calcPercentageDiff(
from['audits'][auditObj].numericValue,
to['audits'][auditObj].numericValue
);
let logColor = '\x1b[37m';
const log = (() => {
if(Math.sign(percentageDiff) === 1) {
logColor = "\x1b[31m";
return `${percentageDiff.toString().replace('-','') + '%'} slower`;
}
else if(Math.sign(percentageDiff) === 0) {
return 'unchanged';
}
else {
logColor = "\x1b[32m";
return `${percentageDiff.toString().replace('-','') + '%'} faster`;
}
})();
console.log(logColor, `${from['audits'][auditObj].title} is ${log}`);
}
}
}
if(argv.from && argv.to) {
compareReports(
getContents(argv.from + '.json'),
getContents(argv.to + '.json')
);
}
else if(argv.url) {
const urlObj = new URL(argv.url);
let dirName = urlObj.host.replace('www.','');
if(urlObj.pathname !== '/') {
dirName = dirName + urlObj.pathname.replace(/\//g,'_');
}
if(!fs.existsSync(dirName)) {
fs.mkdirSync(dirName);
}
launchChromeAndRunLighthouse(argv.url).then(results => {
const prevReports = glob(`${dirName}/*.json`, {
sync: true
});
if(prevReports.length) {
dates = [];
for(report in prevReports) {
dates.push(new Date(path.parse(prevReports[report]).name.replace(/_/g, ':')));
}
const max = dates.reduce(function(a, b) {
return Math.max(a, b);
});
const recentReport = new Date(max).toISOString();
const recentReportContents = getContents(dirName + '/' + recentReport.replace(/:/g, '_') + '.json');
compareReports(recentReportContents, results.js);
}
fs.writeFile(`${dirName}/${results.js['fetchTime'].replace(/:/g, '_')}.json`, results.json, (err) => {
if (err) throw err;
});
});
}
else {
throw "You haven't passed a URL to Lighthouse";
}
@kanagas3

This comment has been minimized.

Copy link

@kanagas3 kanagas3 commented Jul 15, 2020

can we have the same working with Chromium as a CLI ?

@WebDevLuke

This comment has been minimized.

Copy link
Owner Author

@WebDevLuke WebDevLuke commented Jul 15, 2020

can we have the same working with Chromium as a CLI ?

Like a headless browser?

@kanagas3

This comment has been minimized.

Copy link

@kanagas3 kanagas3 commented Jul 16, 2020

can we have the same working with Chromium as a CLI ?

Like a headless browser?
yes similar like headless... i'm using lighthouse-ci and looking for some solution which compares the reports on every run

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.