Last active
August 6, 2018 09:43
-
-
Save martinschierle/a7fb5bf6c8af14f568c111d621b685f2 to your computer and use it in GitHub Desktop.
This file contains 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 puppeteer = require('puppeteer'); | |
const lighthouse = require('lighthouse'); | |
const devices = require('puppeteer/DeviceDescriptors'); | |
const pixelmatch = require('pixelmatch'); | |
const {URL} = require('url'); | |
var fs = require('fs'); | |
var first = true; | |
const phone = devices['Nexus 5X']; | |
async function testPage(url, prefetchList) { | |
var count = 0; | |
const browser = await puppeteer.launch(); | |
const page = await browser.newPage(); | |
// make sure we get the logs from the page, comment in&out as needed | |
//page.on('console', msg => console.log(msg.text())); | |
page.on('error', err=> {console.log('error happen at the page: ', err);}); | |
page.on('pageerror', pageerr=> {console.log('pageerror occurred: ', pageerr);}); | |
// enable network and cpu throttling | |
const client = await page.target().createCDPSession(); | |
await client.send('Network.enable'); | |
await client.send('Network.emulateNetworkConditions', { | |
offline: false, | |
latency: 120, // ms | |
downloadThroughput: 4096, | |
uploadThroughput: 1024, | |
}); | |
await client.send('Emulation.setCPUThrottlingRate', { rate: 4 }); | |
await page.emulate(phone); | |
// event handler for network responses. Here we can alter response, what we'll use this as trigger to inject resource hints for now | |
page.on('response', response => { | |
count++; | |
// log out the first 15 loaded resources to see if the resource hints did something | |
if(count<15) console.log(response.url().substring(0,55)); | |
// we can't inject the links initially, so we do it on second request | |
if(count === 2) { | |
if(prefetchList)for(var i = 0; i < prefetchList.length; i++) { | |
var urlToPreload = prefetchList[i]; | |
page.evaluate((url) => { | |
var e = document.createElement("LINK"); | |
e.rel = "prefetch"; | |
e.href = url; | |
document.head.appendChild(e); | |
//console.log("Injected: " + url); | |
return true; | |
}, urlToPreload).catch(e => {}); | |
} | |
} | |
}); | |
//} | |
//load target url | |
await page.goto(url); | |
// we'll need to wait a sec, otherwise FMP isn't calculated yet | |
await page.waitFor(2000); | |
// collect performance metrics - you can also comment out and use lighthouse below instead | |
var fmp = (await page._client.send('Performance.getMetrics')).metrics.find(x => x.name === "FirstMeaningfulPaint").value/1000; | |
const firstPaint = await page.evaluate("window.performance.getEntriesByName('first-paint')[0].startTime;"); | |
const domInteractive = await page.evaluate("window.performance.timing.domInteractive - window.performance.timing.navigationStart"); | |
const loadEventStart = await page.evaluate("window.performance.timing.loadEventStart - window.performance.timing.navigationStart"); | |
console.log(firstPaint + " - " + fmp + " - " + domInteractive + " - " + loadEventStart); | |
// run lighthouse if needed | |
// Lighthouse will open URL. Puppeteer observes `targetchanged` and sets up network conditions. | |
// Possible race condition. | |
const {lhr} = await lighthouse(url, { | |
port: (new URL(browser.wsEndpoint())).port, | |
output: 'json', | |
logLevel: 'error', // do info for additional details | |
}); | |
console.log(`Lighthouse scores: ${Object.values(lhr.categories).map(c => c.score).join(', ')}`); | |
// get a screenshot of result page. Int he long run we wanna have the whole visual loading progress, but that's more tricky to implement without slowing down page load | |
var filename = "screenshot.png"; | |
if(prefetchList) filename = "screenshot_prefetching.png"; | |
await page.screenshot({path: filename}); | |
await browser.close(); | |
} | |
// ------------ start test case settings ----------- | |
var filesToPreload = [ | |
"ionlyexistfortestingprefetch.js", | |
]; | |
var testURL = "INPUT_TEST_URL_HERE"; | |
// ------------- end test case ------------------- | |
// run test | |
testPage(testURL).then(function() { | |
testPage(testURL, filesToPreload).then(function() { | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment