Skip to content

Instantly share code, notes, and snippets.

@ptigas
Last active January 17, 2019 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptigas/13c480cb12df9236b562362e3cd1672d to your computer and use it in GitHub Desktop.
Save ptigas/13c480cb12df9236b562362e3cd1672d to your computer and use it in GitHub Desktop.
const puppeteer = require('puppeteer');
const fs = require('fs');
var program = require('commander');
program.option('--urls [urls]', 'Urls file')
.option('--chromium [chromium_path]', 'Path of chromium', null)
.option('--output [output]', 'Output path')
.option('--trials [N]', 'Trials', 5)
.parse(process.argv);
const extractDataFromPerformanceTiming = (timing, dataNames) => {
const navigationStart = timing.navigationStart;
return dataNames.reduce((acc, name) => {
acc[name] = timing[name] - navigationStart;
return acc;
}, {});
};
const getTimeFromPerformanceMetrics = (metrics, name) => metrics.metrics.find(x => x.name === name).value * 1000;
const getSimplePagePerformanceMetrics = async (page, url) => {
const client = await page.target().createCDPSession();
await client.send('Performance.enable');
await page.goto(url).catch((err) => {
console.error(url + ' -- Page failed to load -- ' + err);
});
await page.waitFor(5000);
const performanceTiming = JSON.parse(
await page.evaluate(() => JSON.stringify(window.performance.timing)),
);
const performanceMetrics = await client.send('Performance.getMetrics');
// Here are some of the metrics we can get
let res = extractDataFromPerformanceTiming(performanceTiming, [
'requestStart',
'responseStart',
'responseEnd',
'domLoading',
'domInteractive',
'domContentLoadedEventStart',
'domContentLoadedEventEnd',
'domComplete',
'navigationStart',
'loadEventStart',
'loadEventEnd'
]);
res['firstMeaningfulPaint'] = getTimeFromPerformanceMetrics(performanceMetrics, 'FirstMeaningfulPaint') - getTimeFromPerformanceMetrics(performanceMetrics, 'NavigationStart');
return res; // all results are in [ms]
};
(async () => {
let args = {
ignoreHTTPSErrors: true,
ignoreDefaultArgs: true,
headless: false,
userDataDir: "chrome-blank",
args: [
'--disable-background-networking',
'--disable-background-timer-throttling',
'--disable-breakpad',
'--disable-client-side-phishing-detection',
'--disable-default-apps',
'--disable-dev-shm-usage',
'--disable-hang-monitor',
'--disable-popup-blocking',
'--disable-prompt-on-repost',
'--disable-sync',
'--disable-translate',
'--metrics-recording-only',
'--no-first-run',
'--safebrowsing-disable-auto-update',
'--enable-automation',
'--password-store=basic',
'--use-mock-keychain',
'--ignore-certificate-errors',
'--allow-running-insecure-content',
'--no-sandbox',
'--enable-heap-profiling=task-profiler',
]
};
if (program.chromium) {
args['executablePath'] = program.chromium
}
const browser = await puppeteer.launch(args);
for (var run_id=0; run_id<program.trials; run_id++) {
const page = await browser.newPage();
await page.setDefaultNavigationTimeout(60000);
let number_of_images = 0;
page.on('response', async (response) => {
const matches = /.*\.(jpg|png|svg|gif)$/.exec(response.url());
if (matches && (matches.length === 2)) {
number_of_images++;
}
});
let res = [];
var lines = require('fs').readFileSync(program.urls, 'utf-8')
.split('\n')
.filter(Boolean);
for (var line in lines) {
number_of_images = 0;
const url = lines[line];
let metrics = await getSimplePagePerformanceMetrics(page, "https://" + url);
metrics['url'] = url;
metrics['number_of_images'] = number_of_images;
res.push(metrics);
}
let filename = program.output.split(".")
filename[0] = filename[0] + "_" + run_id;
fs.writeFile(filename.join('.'), JSON.stringify(res), (err) => {
if (err) {
console.error(err);
return;
};
console.log("Report has been created");
});
} // end of trials loop
await browser.close();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment