Skip to content

Instantly share code, notes, and snippets.

@acdha
Last active August 29, 2015 13:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save acdha/9191642 to your computer and use it in GitHub Desktop.
Save acdha/9191642 to your computer and use it in GitHub Desktop.
Count the number of domains used to load a page (see http://www.peterbe.com/plog/number-of-domains)
/* global phantom */
// Inspired by https://gist.github.com/cjoudrey/1341747
"use strict";
var system = require('system'),
webPage = require('webpage');
if (system.args.length != 2) {
console.log('Usage:', system.args[0], 'URL');
phantom.exit(2);
}
var url = system.args[1],
original_domain = getDomain(url);
var page = webPage.create();
var maxRenderWait = 30 * 1000,
minQuietTime = 1000, // Minimum time (ms) before assuming load has completed
pendingRequestCount = 0,
lastRequestTime;
var domains = {};
page.viewportSize = { width: 1280, height : 1024 };
page.settings.resourceTimeout = 5000;
page.onConsoleMessage = function(msg, lineNum, sourceId) {
if (lineNum || sourceId) {
console.log('PAGE CONSOLE:', msg, '(Source:', lineNum, sourceId, ')');
} else {
console.log('PAGE CONSOLE:', msg);
}
};
function getDomain(url) {
return url.split('//')[1].split('/')[0];
}
page.onResourceTimeout = function(e) {
console.error('HTTP', e.errorCode, e.errorString, 'loading', e.url);
phantom.exit(1);
};
page.onResourceRequested = function (req) {
pendingRequestCount++;
lastRequestTime = Date.now();
if (req.url.substring(0, 5) != 'data:') {
domains[getDomain(req.url)] = 1;
}
console.debug('Request start', req.id, req.url.substring(0, 70));
};
page.onResourceReceived = function (res) {
if (!res.stage || res.stage === 'end') {
pendingRequestCount--;
console.debug('Request end', res.id, res.status, res.url);
}
};
function checkLoadComplete() {
var elapsed = Date.now() - startTime;
console.debug(pendingRequestCount, 'requests pending;', elapsed, 'ms');
if (pendingRequestCount > 0 && (elapsed < maxRenderWait)) {
return;
}
if (minQuietTime > (Date.now() - lastRequestTime)) {
console.log('Waiting at least', minQuietTime, 'ms for deferred load events to complete');
return;
}
if (elapsed > maxRenderWait) {
console.warn('Render terminated after', elapsed, 'milliseconds; ',
pendingRequestCount, 'requests still pending');
}
var domainCount = 0;
for (var domain in domains) {
console.log('DOMAIN:', domain);
domainCount++;
}
console.log('DOMAIN COUNT:', domainCount);
phantom.exit();
}
var startTime = Date.now();
lastRequestTime = startTime;
console.log('Opening', url);
page.open(url, function (status) {
console.log('onLoadFinished event triggered after', Date.now() - startTime, 'milliseconds');
if (status !== 'success') {
console.error('Error', status, 'loading', url);
phantom.exit(1);
} else {
// Attempt to trigger deferred loaders by scroll to the bottom of the page
page.evaluate(function() {
var __testTriggerScroll = function () {
window.document.body.scrollTop = 0;
window.document.body.scrollTop = document.body.scrollHeight;
console.log("Scrolled window");
};
window.addEventListener("load", function load() {
window.setTimeout(__testTriggerScroll, 100);
console.log('window load event fired, triggering scroll event');
});
window.setTimeout(__testTriggerScroll, 50);
});
}
});
// We'll check under the minQuietTime threshold to avoid aliasing:
setInterval(checkLoadComplete, Math.floor(minQuietTime / 3));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment