fixing jshint part 2

This commit is contained in:
soulgalore 2014-08-13 22:54:01 +02:00
parent a8ad24727c
commit 6c1ce7aad5
29 changed files with 426 additions and 306 deletions

View File

@ -1,5 +1,5 @@
#!/usr/bin/env node
var Runner = require("../lib/runner");
var Runner = require('../lib/runner');
var r = new Runner();

View File

@ -4,7 +4,6 @@
* and other contributors
* Released under the Apache 2.0 License
*/
var util = require('../../util');
var Aggregator = require('../../aggregator');
module.exports = new Aggregator('gpsi.gscore', 'Google Page Speed Insights Score',

View File

@ -26,7 +26,9 @@ exports.processPage = function(pageData) {
var timings = Object.keys(entry.timings);
for (var i = 0; i < timings.length; i++) {
if (timings[i] === 'comment') continue;
if (timings[i] === 'comment') {
continue;
}
if (timeMetrics.hasOwnProperty(timings[i])) {
timeMetrics[timings[i]].push(Number(entry.timings[timings[i]]));
} else {

View File

@ -4,7 +4,6 @@
* and other contributors
* Released under the Apache 2.0 License
*/
var util = require('../../util');
var Aggregator = require('../../aggregator');
module.exports = new Aggregator('har.pageWeight', 'Total page weight (including all assets) from HAR',

View File

@ -14,6 +14,8 @@ module.exports = new Aggregator('browserScaledImages',
if (pageData.yslow) {
if (pageData.yslow.g.avoidscalingimages) {
this.stats.push(pageData.yslow.g.avoidscalingimages.components.length);
} else this.stats.push(0);
} else {
this.stats.push(0);
}
}
});

View File

@ -12,7 +12,8 @@ module.exports = new Aggregator('criticalPathScore',
'', 1,
function(pageData) {
if (pageData.yslow) {
if (pageData.yslow.g.criticalpath)
if (pageData.yslow.g.criticalpath) {
this.stats.push(pageData.yslow.g.criticalpath.score);
}
}
});

View File

@ -16,8 +16,9 @@ module.exports = new Aggregator('cssWeight', 'CSS Weight',
// also YSlow/PhantomJs don't know about compressed size
var self = this;
pageData.yslow.comps.forEach(function(comp) {
if (comp.type === 'css')
if (comp.type === 'css') {
self.stats.push(comp.size);
}
});
}
});

View File

@ -16,8 +16,9 @@ module.exports = new Aggregator('cssWeightPerPage', 'CSS File Weight Per Page',
// also YSlow/PhantomJs don't know about compressed size
var size = 0;
pageData.yslow.comps.forEach(function(comp) {
if (comp.type === 'css')
if (comp.type === 'css') {
size += comp.size;
}
});
this.stats.push(size);
}

View File

@ -16,8 +16,9 @@ module.exports = new Aggregator('docWeight', 'Document Weight',
// also YSlow/PhantomJs don't know about compressed size
var self = this;
pageData.yslow.comps.forEach(function(comp) {
if (comp.type === 'doc')
if (comp.type === 'doc') {
self.stats.push(comp.size);
}
});
}
});

View File

@ -13,6 +13,8 @@ module.exports = new Aggregator('domElements', 'Number of DOM elements',
if (pageData.yslow) {
if (pageData.yslow.g.mindom) {
this.stats.push(pageData.yslow.g.mindom.components.length);
} else this.stats.push(0);
} else {
this.stats.push(0);
}
}
});

View File

@ -16,8 +16,9 @@ module.exports = new Aggregator('imageWeight', 'Image Weight',
// also YSlow/PhantomJs don't know about compressed size
var self = this;
pageData.yslow.comps.forEach(function(comp) {
if (comp.type === 'image')
if (comp.type === 'image') {
self.stats.push(comp.size);
}
});
}
});

View File

@ -16,8 +16,9 @@ module.exports = new Aggregator('imagesWeightPerPage', 'Images Weight Per Page',
// also YSlow/PhantomJs don't know about compressed size
var size = 0;
pageData.yslow.comps.forEach(function(comp) {
if (comp.type === 'image')
if (comp.type === 'image') {
size += comp.size;
}
});
this.stats.push(size);
}

View File

@ -14,6 +14,8 @@ module.exports = new Aggregator('jsSyncInHead',
if (pageData.yslow) {
if (pageData.yslow.g.syncjsinhead) {
this.stats.push(pageData.yslow.g.syncjsinhead.components.length);
} else this.stats.push(0);
} else {
this.stats.push(0);
}
}
});

View File

@ -16,8 +16,9 @@ module.exports = new Aggregator('jsWeight', 'JS Weight',
// also YSlow/PhantomJs don't know about compressed size
var self = this;
pageData.yslow.comps.forEach(function(comp) {
if (comp.type === 'js')
if (comp.type === 'js') {
self.stats.push(comp.size);
}
});
}
});

View File

@ -16,8 +16,9 @@ module.exports = new Aggregator('jsWeightPerPage', 'JS File Weight Per Page',
// also YSlow/PhantomJs don't know about compressed size
var size = 0;
pageData.yslow.comps.forEach(function(comp) {
if (comp.type === 'js')
if (comp.type === 'js') {
size += comp.size;
}
});
this.stats.push(size);
}

View File

@ -12,14 +12,15 @@ module.exports = new Aggregator('maxRequestsPerHost', 'Max requests per domain',
'', 2,
function(pageData) {
if (pageData.yslow) {
var hostAndRequests = util.getAssetsPerDomain(pageData.yslow.comps),
keys = Object.keys(hostAndRequests),
maxRequestsPerHost = 0;
var hostAndRequests = util.getAssetsPerDomain(pageData.yslow.comps);
var keys = Object.keys(hostAndRequests);
var maxRequestsPerHost = 0;
// take the hosts with the most requests
for (var i = 0; i < keys.length; i++) {
if (hostAndRequests[keys[i]] > maxRequestsPerHost)
if (hostAndRequests[keys[i]] > maxRequestsPerHost) {
maxRequestsPerHost = hostAndRequests[keys[i]];
}
}
this.stats.push(maxRequestsPerHost);
}

View File

@ -13,6 +13,8 @@ module.exports = new Aggregator('pagesWithSPOF', 'Pages with SPOF',
if (pageData.yslow) {
if (pageData.yslow.g.spof) {
this.stats.push(1);
} else this.stats.push(0);
} else {
this.stats.push(0);
}
}
});

View File

@ -13,6 +13,8 @@ module.exports = new Aggregator('redirectsPerPage', 'Redirects Per Page',
if (pageData.yslow) {
if (pageData.yslow.g.redirects) {
this.stats.push(pageData.yslow.g.redirects.components.length);
} else this.stats.push(0);
} else {
this.stats.push(0);
}
}
});

View File

@ -10,6 +10,7 @@ module.exports = new Aggregator('requests', 'Number of requests per page',
'Fewer requests are always faster than many requests.',
'', 1,
function (pageData) {
if (pageData.yslow)
if (pageData.yslow) {
this.stats.push(pageData.yslow.r);
}
});

View File

@ -15,10 +15,10 @@ module.exports = new Aggregator('requestsWithoutExpires',
if (pageData.yslow) {
var requestsWithoutExpire = 0;
pageData.yslow.comps.forEach(function(comp) {
if (util.getCacheTime(comp) === 0)
if (util.getCacheTime(comp) === 0) {
requestsWithoutExpire++;
}
});
this.stats.push(requestsWithoutExpire);
}
});

View File

@ -4,6 +4,7 @@ module.exports = new Aggregator('ruleScore', 'Rule Score',
'The sitespeed.io total rule score for all the pages',
'', 0,
function (pageData) {
if (pageData.yslow)
if (pageData.yslow) {
this.stats.push(pageData.yslow.o);
}
});

View File

@ -12,14 +12,15 @@ module.exports = new Aggregator('singleDomainRequests', 'Domains with only one r
'', 2,
function (pageData) {
if (pageData.yslow) {
var hostAndRequests = util.getAssetsPerDomain(pageData.yslow.comps),
keys = Object.keys(hostAndRequests),
domainsWithOneRequest = 0;
var hostAndRequests = util.getAssetsPerDomain(pageData.yslow.comps);
var keys = Object.keys(hostAndRequests);
var domainsWithOneRequest = 0;
// take the hosts with the most requests
for (var i = 0; i < keys.length; i++) {
if (hostAndRequests[keys[i]] === 1)
if (hostAndRequests[keys[i]] === 1) {
domainsWithOneRequest++;
}
}
this.stats.push(domainsWithOneRequest);
}

View File

@ -14,6 +14,8 @@ module.exports = new Aggregator('spofPerPage',
if (pageData.yslow) {
if (pageData.yslow.g.spof) {
this.stats.push(pageData.yslow.g.spof.components.length);
} else this.stats.push(0);
} else {
this.stats.push(0);
}
}
});

View File

@ -36,14 +36,15 @@ module.exports = {
urls.forEach(function(u) {
queue.push({
"url": u,
"wpt": wpt
'url': u,
'wpt': wpt
}, function(data, err) {
if (err) {
log.log('error', 'Error running WebPageTest: ' + err);
errors[u] = err;
} else
} else {
pageData[u] = data;
}
});
});
@ -80,13 +81,13 @@ function analyzeUrl(args, asyncDoneCallback) {
wpt.runTest(url, wptOptions, function(err, data) {
if (err) {
log.log('error', "WebPageTest couldn't fetch info for url " + url + '(' +
log.log('error', 'WebPageTest couldnt fetch info for url ' + url + '(' +
JSON.stringify(err) + ')');
asyncDoneCallback(undefined, err);
return;
}
var id = data.response.data.testId;
// var id = data.response.data.testId;
/*
console.log('Test id:' + data.response.data.testId);
@ -107,7 +108,7 @@ function analyzeUrl(args, asyncDoneCallback) {
});
wpt.getHARData(id, {}, function(err,data) {
console.log("har:" + JSON.stringify(data));
console.log('har:' + JSON.stringify(data));
});
*/
@ -118,11 +119,13 @@ function analyzeUrl(args, asyncDoneCallback) {
fs.writeFile(jsonPath, JSON.stringify(data), function(err) {
if (err) {
log.log('error', "WebPageTest couldn't store file for url " + url + '(' +
log.log('error', 'WebPageTest couldnt store file for url ' + url + '(' +
err + ')');
asyncDoneCallback(undefined, err);
} else asyncDoneCallback(data, undefined);
} else {
asyncDoneCallback(data, undefined);
}
});
});

View File

@ -9,7 +9,7 @@ urlParser = require('url'),
fs = require('fs-extra'),
path = require('path'),
supportedBrowsers = ['chrome','ie','firefox'],
config = require("nomnom").options({
config = require('nomnom').options({
url: {
abbr: 'u',
metavar: '<URL>',
@ -21,7 +21,7 @@ config = require("nomnom").options({
help: 'The path to a plain text file with one URL on each row. Each line must end with a new line in the file.',
callback: function(file) {
if (!fs.existsSync(file))
return "Couldn't find the file:" + file;
return 'Could not find the file:' + file;
}
},
sites: {
@ -29,7 +29,7 @@ config = require("nomnom").options({
help: 'The path to a plain text file with one URL on each row. Each line must end with a new line in the file.',
callback: function(file) {
if (!fs.existsSync(file))
return "Couldn't find the file:" + file;
return 'Couldnt find the file:' + file;
}
},
version: {
@ -37,7 +37,7 @@ config = require("nomnom").options({
abbr: 'v',
help: 'Display the sitespeed.io version',
callback: function() {
return require("../package.json").version;
return require('../package.json').version;
}
},
deep: {
@ -46,8 +46,9 @@ config = require("nomnom").options({
default: 1,
help: 'How deep to crawl.',
callback: function(deep) {
if (deep != parseInt(deep))
return "You must specify an integer";
if (deep !== parseInt(deep)) {
return 'You must specify an integer';
}
}
},
containInPath: {
@ -66,10 +67,12 @@ config = require("nomnom").options({
default: 5,
help: 'The number of that will analyze pages.',
callback: function(threads) {
if (threads != parseInt(threads))
return "You must specify an integer";
else if (parseInt(threads) <= 0)
return "You must specify a positive integer";
if (threads !== parseInt(threads)) {
return 'You must specify an integer';
}
else if (parseInt(threads) <= 0) {
return 'You must specify a positive integer';
}
}
},
name: {
@ -89,14 +92,16 @@ config = require("nomnom").options({
callback: function(file) {
if (!fs.existsSync(file)) {
fs.mkdirs(file, function(err){
if (err) return "Couldn't create the result base dir:" + err;
if (err) {
return 'Couldnt create the result base dir:' + err;
}
});
}
}
},
userAgent: {
metavar: '<USER-AGENT>',
default: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36",
default: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36',
help: 'The full User Agent string, default is Chrome for MacOSX. You can also set the value as iphone or ipad (will automagically change the viewport)'
},
viewPort: {
@ -110,8 +115,9 @@ config = require("nomnom").options({
default: 'yslow-3.1.8-sitespeed.js',
help: 'The compiled YSlow file.',
callback: function(file) {
if (!fs.existsSync(file))
return "Couldn't find the file:" + fs.realpathSync(file);
if (!fs.existsSync(file)) {
return 'Couldnt find the file:' + fs.realpathSync(file);
}
}
},
ruleSet: {
@ -133,13 +139,14 @@ config = require("nomnom").options({
metavar: '<BROWSER>',
help: 'Choose which browser to use to collect timing data. You can set multiple browsers in a comma separated list (firefox|chrome|ie)',
callback: function(browsers) {
b = browsers.split(","),
var b = browsers.split(','),
invalidBrowsers = b.filter(function(browser) {
return supportedBrowsers.indexOf(browser) < 0;
});
if (invalidBrowsers.length > 0)
return "You specified a browser that is not supported:" + invalidBrowsers;
if (invalidBrowsers.length > 0) {
return 'You specified a browser that is not supported:' + invalidBrowsers;
}
}
},
profile: {
@ -154,10 +161,10 @@ config = require("nomnom").options({
default: 3,
help: 'The number of times you should test each URL when fetching timing metrics. Default is three times',
callback: function(n) {
if (n != parseInt(n))
return "You must specify an integer";
if (n !== parseInt(n))
return 'You must specify an integer';
else if (parseInt(n) <= 0)
return "You must specify a positive integer";
return 'You must specify a positive integer';
}
},
screenshot: {
@ -175,15 +182,15 @@ config = require("nomnom").options({
threshold: {
default: 90,
metavar: '[0-100]',
help: "Threshold score for tests, will be used of no mathing thresholdFile with values match. Use : --threshold 95"
help: 'Threshold score for tests, will be used of no mathing thresholdFile with values match. Use : --threshold 95'
},
thresholdFile: {
metavar: '<FILE>',
help: "A file containing JSON like {\"overall\": 90, \"thirdpartyversions\": 85}"
help: 'A file containing JSON like {\'overall\': 90, \'thirdpartyversions\': 85}'
},
timingsThresholdFile: {
metavar: '<FILE>',
help: "A file containing JSON like ..."
help: 'A file containing JSON like ...'
},
csv: {
flag: true,
@ -294,13 +301,13 @@ var startPath = (config.resultBaseDir.charAt(0) === path.sep) ? config.resultBas
if (config.url) {
config.urlObject = urlParser.parse(config.url);
config.run.absResultDir = path.join(startPath, config.urlObject.hostname, dateFormat(config.run.date, "yyyy-mm-dd-HH-MM-ss") );
config.run.absResultDir = path.join(startPath, config.urlObject.hostname, dateFormat(config.run.date, 'yyyy-mm-dd-HH-MM-ss') );
} else if (config.file) {
// TODO handle the file name in a good way if it contains chars that will not fit in a dir
config.run.absResultDir = path.join(startPath, config.file, dateFormat(config.run.date, "yyyy-mm-dd-HH-MM-ss") );
config.run.absResultDir = path.join(startPath, config.file, dateFormat(config.run.date, 'yyyy-mm-dd-HH-MM-ss') );
} else if (config.sites) {
// The log file will end up here
config.run.absResultDir = path.join(startPath, 'sites', dateFormat(config.run.date, "yyyy-mm-dd-HH-MM-ss"));
config.run.absResultDir = path.join(startPath, 'sites', dateFormat(config.run.date, 'yyyy-mm-dd-HH-MM-ss'));
}
// Parse the proxy info as a real URL
@ -308,20 +315,22 @@ if (config.proxy) {
config.urlProxyObject = urlParser.parse(config.proxy);
}
if (config.thresholdFile)
if (config.thresholdFile) {
config.thresholds = require(config.thresholdFile);
}
if (config.timingsThresholdFile)
if (config.timingsThresholdFile) {
config.timingThresholds = require(timingsThresholdFile);
else
}
else {
config.timingThresholds = require('../conf/junit-timings.json');
}
// decide which rules to use ...
if (config.profile === 'mobile') {
config.rules= require('../conf/mobile-rules.json');
config.ruleSet = "sitespeed.io-mobile";
config.userAgent = "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25";
config.viewPort = "320x444";
config.ruleSet = 'sitespeed.io-mobile';
config.userAgent = 'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25';
config.viewPort = '320x444';
}
else {
config.rules= require(config.limitFile);
@ -332,9 +341,9 @@ config.summaryBoxes = ['ruleScore'];
config.sitesColumns = ['requests','criticalPathScore','pageWeight','cacheTime','ruleScore'];
if (config.runYslow)
config.pageColumns = ['yslow.assets.js','yslow.assets.css','yslow.assets.img','yslow.requests','rules.expiresmod.items','yslow.pageWeight', 'rules.avoidscalingimages.items','rules.criticalpath'];
if (config.runYslow) {
config.pageColumns = ['yslow.assets.js','yslow.assets.css','yslow.assets.img','yslow.requests','rules.expiresmod.items','yslow.pageWeight', 'rules.avoidscalingimages.items','rules.criticalpath'];
}
if (config.columns) {
config.pageColumns = config.columns[0].split(',');
}
@ -367,14 +376,17 @@ if (config.browser) {
if (config.boxes) {
if (config.boxes[0].indexOf('+')===0) {
config.boxes[0].split(',').forEach(function (box) {
if (box.indexOf('+')===0)
if (box.indexOf('+')===0) {
config.summaryBoxes.push(box.substring(1));
else
}
else {
config.summaryBoxes.push(box);
}
});
}
else
else {
config.summaryBoxes = config.boxes[0].split(',');
}
}
config.dataDir = 'data';

View File

@ -62,8 +62,9 @@ module.exports.registerHelpers = function registerHelpers() {
});
hb.registerHelper('isLowerThan', function(value, limit, options) {
if (value < limit)
if (value < limit) {
return options.fn(this);
}
});
hb.registerHelper('getDecimals', function(value, decimals) {
@ -83,9 +84,12 @@ module.exports.registerHelpers = function registerHelpers() {
});
hb.registerHelper('getMatchingRuleName', function(id, rules) {
if (rules.hasOwnProperty(id))
if (rules.hasOwnProperty(id)) {
return rules[id].name;
else return id;
}
else {
return id;
}
});
hb.registerHelper('prettyOSName', function(name) {
@ -93,10 +97,12 @@ module.exports.registerHelpers = function registerHelpers() {
// and windows has the following names, change them to
// just Windows
var windows = ['xp', 'windows', 'win8', 'win7'];
if (windows.indexOf(name)>-1)
if (windows.indexOf(name)>-1) {
return 'Windows';
else
}
else {
return name.substr(0, 1).toUpperCase() + name.substr(1);
}
});
hb.registerHelper('capitalize', function(word) {
@ -104,8 +110,9 @@ module.exports.registerHelpers = function registerHelpers() {
});
hb.registerHelper('getPlural', function(value) {
if (value>1)
if (value>1) {
return 's';
}
return '';
});
@ -139,23 +146,28 @@ module.exports.registerHelpers = function registerHelpers() {
hb.registerHelper('getSiteAggregatedValue', function(siteName, type, metric, aggregates) {
var value = '';
aggregates[siteName].forEach(function (a) {
if (a.id === metric)
if (a.id === metric) {
value = a.stats[type];
}
});
return value;
});
hb.registerHelper('getWPTWaterFall', function(run, whichView) {
// TypeError: Cannot read property 'images' of undefined
if (Array.isArray(run))
if (run[0][whichView])
// TypeError: Cannot read property 'images' of undefined
if (Array.isArray(run)) {
if (run[0][whichView]) {
return run[0][whichView].images.waterfall;
else return;
else
if (run)
return run[whichView].images.waterfall;
else return;
} else {
return;
}
} else
if (run) {
return run[whichView].images.waterfall;
} else {
return;
}
});

View File

@ -11,11 +11,9 @@ var hb = require('handlebars'),
config = require('./conf'),
helpers = require('./hb-helpers'),
columnsMetaData = require('../conf/columnsMetaData.json'),
async = require("async"),
async = require('async'),
util = require('./util');
module.exports = HTMLRenderer;
var compiledTemplates = {},
compiledPartials = {},
ruleDictionary = {};
@ -28,7 +26,9 @@ function HTMLRenderer() {
HTMLRenderer.prototype.copyAssets = function (toDir, cb) {
fs.copy(path.join(__dirname, '../assets/'), toDir, function (err) {
if (err) throw err;
if (err) {
throw err;
}
cb();
});
};
@ -39,19 +39,19 @@ HTMLRenderer.prototype.renderPage = function (url, pageData, cb) {
var renderData = {};
if (pageData.yslow) {
renderData = {
"url": pageData.yslow.originalUrl,
"score": pageData.yslow.o,
"size": util.getSize(pageData.yslow.comps),
"rules": pageData.yslow.g,
"assets": pageData.yslow.comps,
"noOfDomains": util.getNumberOfDomains(pageData.yslow.comps),
"timeSinceLastModificationStats": util.getLastModStats(pageData.yslow.comps),
"cacheTimeStats": util.getCacheTimeStats(pageData.yslow.comps),
"noOfAssetsThatIsCached": (pageData.yslow.comps.length - pageData.yslow.g.expiresmod.components.length),
"assetsPerDomain": util.getAssetsPerDomain(pageData.yslow.comps),
"assetsPerContentType": util.getAssetsPerContentType(pageData.yslow.comps),
"sizePerContentType": util.getAssetsSizePerContentType(pageData.yslow.comps),
"ruleDictionary": pageData.yslow.dictionary.rules,
'url': pageData.yslow.originalUrl,
'score': pageData.yslow.o,
'size': util.getSize(pageData.yslow.comps),
'rules': pageData.yslow.g,
'assets': pageData.yslow.comps,
'noOfDomains': util.getNumberOfDomains(pageData.yslow.comps),
'timeSinceLastModificationStats': util.getLastModStats(pageData.yslow.comps),
'cacheTimeStats': util.getCacheTimeStats(pageData.yslow.comps),
'noOfAssetsThatIsCached': (pageData.yslow.comps.length - pageData.yslow.g.expiresmod.components.length),
'assetsPerDomain': util.getAssetsPerDomain(pageData.yslow.comps),
'assetsPerContentType': util.getAssetsPerContentType(pageData.yslow.comps),
'sizePerContentType': util.getAssetsSizePerContentType(pageData.yslow.comps),
'ruleDictionary': pageData.yslow.dictionary.rules,
};
}
else {
@ -63,9 +63,9 @@ HTMLRenderer.prototype.renderPage = function (url, pageData, cb) {
renderData.wptData = pageData.webpagetest;
renderData.config = config;
renderData.pageMeta = {
"path": "../",
"title": "Page data, collected by sitespeed.io for page " + url,
"description": "All data collected for this individual page."
'path': '../',
'title': 'Page data, collected by sitespeed.io for page ' + url,
'description': 'All data collected for this individual page.'
};
var hash = util.getUrlHash(url);
renderHtmlToFile('page', renderData, cb, hash + '.html', 'pages');
@ -73,12 +73,12 @@ HTMLRenderer.prototype.renderPage = function (url, pageData, cb) {
HTMLRenderer.prototype.renderRules = function (cb) {
var renderData = {
"ruleDictionary": ruleDictionary,
"config": config,
"pageMeta": {
"title": "The sitespeed.io rules used by this run",
"description": "",
"isRules": true
'ruleDictionary': ruleDictionary,
'config': config,
'pageMeta': {
'title': 'The sitespeed.io rules used by this run',
'description': '',
'isRules': true
}
};
renderHtmlToFile('rules', renderData, cb);
@ -91,8 +91,8 @@ HTMLRenderer.prototype.renderSites = function(sitesAggregates, cb) {
// Add all sites data sorted
Object.keys(sitesAggregates).forEach(function(site) {
sitesAndAggregates.push({
"site": site,
"aggregates": sitesAggregates[site].filter(function(box) {
'site': site,
'aggregates': sitesAggregates[site].filter(function(box) {
return (config.sitesColumns.indexOf(box.id) > -1);
}).sort(function(box, box2) {
return config.sitesColumns.indexOf(box.id) - config.sitesColumns.indexOf(box2.id);
@ -100,16 +100,16 @@ HTMLRenderer.prototype.renderSites = function(sitesAggregates, cb) {
});
});
var renderData = {
"sitesAndAggregates": sitesAndAggregates,
"columns": config.sitesColumns,
"config": config,
"columnsMeta": columnsMetaData,
"ruleDictionary": ruleDictionary,
"pageMeta": {
"title": "",
"description": "",
"hideMenu": true,
"isSites": true
'sitesAndAggregates': sitesAndAggregates,
'columns': config.sitesColumns,
'config': config,
'columnsMeta': columnsMetaData,
'ruleDictionary': ruleDictionary,
'pageMeta': {
'title': '',
'description': '',
'hideMenu': true,
'isSites': true
}
};
renderHtmlToFile('sites', renderData, cb, 'sites.html', '..');
@ -118,12 +118,12 @@ HTMLRenderer.prototype.renderSites = function(sitesAggregates, cb) {
HTMLRenderer.prototype.renderScreenshots = function (pages, cb) {
var renderData = {
"pages": pages,
"config": config,
"pageMeta": {
"title": "",
"description": "",
"isScreenshots": true
'pages': pages,
'config': config,
'pageMeta': {
'title': '',
'description': '',
'isScreenshots': true
}
};
renderHtmlToFile('screenshots', renderData, cb);
@ -132,17 +132,17 @@ renderHtmlToFile('screenshots', renderData, cb);
HTMLRenderer.prototype.renderErrors = function (downloadErrors, analysisErrors, cb) {
var renderData = {
"errors": {
"downloadErrorUrls": downloadErrors,
"analysisErrorUrls": analysisErrors
'errors': {
'downloadErrorUrls': downloadErrors,
'analysisErrorUrls': analysisErrors
},
"totalErrors": Object.keys(downloadErrors).length + Object.keys(analysisErrors).length ,
"config": config,
"numberOfPages":this.numberOfAnalyzedPages,
"pageMeta": {
"title": "Pages that couldn't be analyzed",
"description": "Here are the pages that couldn't be analyzed by sitespeed.io",
"isErrors": true
'totalErrors': Object.keys(downloadErrors).length + Object.keys(analysisErrors).length ,
'config': config,
'numberOfPages':this.numberOfAnalyzedPages,
'pageMeta': {
'title': 'Pages that couldnt be analyzed',
'description': 'Here are the pages that couldnt be analyzed by sitespeed.io',
'isErrors': true
}
};
renderHtmlToFile('errors', renderData, cb);
@ -156,24 +156,24 @@ HTMLRenderer.prototype.renderSummary = function(aggregates, cb) {
return config.summaryBoxes.indexOf(box.id) - config.summaryBoxes.indexOf(box2.id);
});
var summaryData = {
"aggregates": filtered,
"config": config,
"numberOfPages": this.numberOfAnalyzedPages,
"pageMeta": {
"title": "Summary of the sitespeed.io result",
"description": "A executive summary.",
"isSummary": true
'aggregates': filtered,
'config': config,
'numberOfPages': this.numberOfAnalyzedPages,
'pageMeta': {
'title': 'Summary of the sitespeed.io result',
'description': 'A executive summary.',
'isSummary': true
}
};
var detailedData = {
"aggregates": aggregates,
"config": config,
"numberOfPages": this.numberOfAnalyzedPages,
"pageMeta": {
"title": "In details summary of the sitespeed.io result",
"description": "The summary in details.",
"isDetailedSummary": true
'aggregates': aggregates,
'config': config,
'numberOfPages': this.numberOfAnalyzedPages,
'pageMeta': {
'title': 'In details summary of the sitespeed.io result',
'description': 'The summary in details.',
'isDetailedSummary': true
}
};
@ -192,15 +192,15 @@ HTMLRenderer.prototype.renderSummary = function(aggregates, cb) {
HTMLRenderer.prototype.renderPages = function (pages, cb) {
var renderData = {
"pages": pages,
"columnsMeta": columnsMetaData,
"config": config,
"ruleDictionary": ruleDictionary,
"numberOfPages":this.numberOfAnalyzedPages,
"pageMeta": {
"title": "All pages information",
"description": "All request data, for all the pages",
"isPages": true
'pages': pages,
'columnsMeta': columnsMetaData,
'config': config,
'ruleDictionary': ruleDictionary,
'numberOfPages':this.numberOfAnalyzedPages,
'pageMeta': {
'title': 'All pages information',
'description': 'All request data, for all the pages',
'isPages': true
}
};
@ -212,42 +212,47 @@ HTMLRenderer.prototype.renderAssets = function (assets, cb) {
return asset2.count - asset.count;
});
if (sorted.length>200)
if (sorted.length>200) {
sorted.length = 200;
}
var renderData = {
"assets": sorted,
"config": config,
"numberOfPages":this.numberOfAnalyzedPages,
"pageMeta": {
"title": "The most used assets",
"description": "A list of the most used assets for the analyzed pages.",
"isAssets": true
'assets': sorted,
'config': config,
'numberOfPages':this.numberOfAnalyzedPages,
'pageMeta': {
'title': 'The most used assets',
'description': 'A list of the most used assets for the analyzed pages.',
'isAssets': true
}
};
renderHtmlToFile('assets', renderData, cb);
};
function renderHtmlToFile(template, renderData, cb, fileName, optionalPath) {
fileName = fileName || (template + ".html");
fileName = fileName || (template + '.html');
optionalPath = optionalPath || '';
var result = compiledTemplates[template](renderData);
var file = path.join(config.run.absResultDir, optionalPath, fileName);
fs.outputFile(file, result, function(err) {
if (err)
log.log('error', "Couldn't write the file " + file + ' err:' + err);
else
log.log('info', "Wrote file " + fileName);
if (err) {
log.log('error', 'Couldnt write the file ' + file + ' err:' + err);
}
else {
log.log('info', 'Wrote file ' + fileName);
}
cb();
});
}
function precompileTemplates() {
compiledTemplates = compileTemplates(path.join(__dirname, "../templates/"));
compiledPartials = compileTemplates(path.join(__dirname, "../templates/partials/"));
compiledTemplates = compileTemplates(path.join(__dirname, '../templates/'));
compiledPartials = compileTemplates(path.join(__dirname, '../templates/partials/'));
for (var key in compiledPartials) {
if(compiledPartials.hasOwnProperty(key)) {
hb.registerPartial(key, compiledPartials[key]);
}
}
}
@ -255,8 +260,11 @@ function compileTemplates(folderPath) {
// TODO would be cool to do this async
var templates = {};
fs.readdirSync(folderPath).forEach(function (file) {
if (!fs.lstatSync(path.join(folderPath + file)).isDirectory())
if (!fs.lstatSync(path.join(folderPath + file)).isDirectory()) {
templates[path.basename(file, '.hb')] = hb.compile(fs.readFileSync(path.join(folderPath + file), 'utf8'));
}
});
return templates;
}
module.exports = HTMLRenderer;

View File

@ -15,7 +15,7 @@ var crawler = require('./crawler'),
dateFormat = require('dateformat'),
fs = require('fs-extra'),
config = require('./conf'),
async = require("async"),
async = require('async'),
urlParser = require('url'),
os = require('os'),
EOL = os.EOL,
@ -23,7 +23,7 @@ var crawler = require('./crawler'),
childProcess = require('child_process'),
log = require('winston');
module.exports = Runner;
function Runner() {
this.analyzer = new Analyzer();
@ -51,11 +51,15 @@ Runner.prototype.run = function(finshedCb) {
],
function(err, results){
if (err) throw err;
if (config.sites)
if (err) {
throw err;
}
if (config.sites) {
self._analyzeSites(finshedCb);
else
}
else {
self._analyzeSite(finshedCb);
}
});
};
@ -65,18 +69,22 @@ Runner.prototype._analyzeSites = function(cb) {
// store all site data here, use it when parsing
self.sites = {};
var urls = fs.readFile(config.sites, function(err, data) {
if (err) throw err;
fs.readFile(config.sites, function(err, data) {
if (err) {
throw err;
}
var urls = data.toString().split(EOL);
var queue = async.queue(self._setupConfigurationForSite, 1);
log.log('info', 'Analyze ' + urls.length + ' sites');
urls.forEach(function(url) {
if (url !== "") queue.push({
if (url !== '') {
queue.push({
'url': url,
'runner': self
}, function() {
log.log('info', "Finished with site " + url);
log.log('info', 'Finished with site ' + url);
});
}
});
queue.drain = function() {
@ -89,8 +97,9 @@ Runner.prototype._analyzeSites = function(cb) {
}
},
function(err, results) {
if (!err)
log.log('info', "Wrote sites result to " + config.run.absResultDir);
if (!err) {
log.log('info', 'Wrote sites result to ' + config.run.absResultDir);
}
cb();
});
};
@ -106,15 +115,17 @@ Runner.prototype._setupConfigurationForSite = function(args, cb) {
config.resultBaseDir);
config.run.absResultDir = path.join(startPath, 'sites', dateFormat(config.run.date,
"yyyy-mm-dd-HH-MM-ss"), config.urlObject.hostname);
'yyyy-mm-dd-HH-MM-ss'), config.urlObject.hostname);
// setup the directories needed
var dataDir = path.join(config.run.absResultDir, config.dataDir);
fs.mkdirs(dataDir, function(err) {
if (err) {
log.log('error', "Couldn't create the data dir:" + dataDir + ' ' + err);
log.log('error', 'Couldnt create the data dir:' + dataDir + ' ' + err);
throw err;
} else args.runner._analyzeSite(cb);
} else {
args.runner._analyzeSite(cb);
}
});
};
@ -145,8 +156,9 @@ Runner.prototype._analyzeSite = function(cb) {
self._createOutput(downloadErrors, analysisErrors, cb);
}
], function(err, result) {
if (err)
if (err) {
log.log('error', err);
}
cb();
});
};
@ -154,18 +166,19 @@ Runner.prototype._analyzeSite = function(cb) {
Runner.prototype._fineTuneUrls = function (okUrls, errorUrls, callback) {
var downloadErrors = {};
Object.keys(errorUrls).forEach(function(url) {
log.log('error', "Failed to download " + url);
log.log('error', 'Failed to download ' + url);
downloadErrors[url] = errorUrls[url];
});
// limit
if (config.maxPagesToTest) {
if (okUrls.length > config.maxPagesToTest)
if (okUrls.length > config.maxPagesToTest) {
okUrls.length = config.maxPagesToTest;
}
}
if (okUrls.length === 0) {
log.log('info', "Didn't get any URLs");
callback(new Error("No URLs to analyze"), okUrls, downloadErrors);
log.log('info', 'Didnt get any URLs');
callback(new Error('No URLs to analyze'), okUrls, downloadErrors);
}
else {
saveUrls(okUrls);
@ -175,14 +188,16 @@ Runner.prototype._fineTuneUrls = function (okUrls, errorUrls, callback) {
Runner.prototype._fetchUrls = function (crawler, callback) {
if (config.url) {
log.log('info', "Will crawl from start point " + config.url +
" with crawl depth " + config.deep);
log.log('info', 'Will crawl from start point ' + config.url +
' with crawl depth ' + config.deep);
crawler.crawl(config.url, function(okUrls, errorUrls) {
callback(null, okUrls, errorUrls);
});
} else {
fs.readFile(config.file, function (err, data) {
if (err) throw err;
if (err) {
throw err;
}
var urls = data.toString().split(EOL);
urls = urls.filter(function(l) {
return l.length > 0;
@ -196,7 +211,7 @@ Runner.prototype._fetchUrls = function (crawler, callback) {
Runner.prototype._analyze = function (urls, downloadErrors, callback) {
var analysisErrors = {};
var self = this;
log.log('info', "Will analyze " + urls.length + " pages");
log.log('info', 'Will analyze ' + urls.length + ' pages');
this.analyzer.analyze(urls, this.collector, downloadErrors, analysisErrors, function(err, url, pageData) {
if (err) {
@ -206,8 +221,9 @@ Runner.prototype._analyze = function (urls, downloadErrors, callback) {
return;
}
if (config.junit)
if (config.junit) {
self.junitRenderer.renderForEachPage(url, pageData);
}
self.htmlRenderer.renderPage(url, pageData, function() {});
}, callback);
};
@ -226,7 +242,9 @@ function createDataDir(cb) {
// create the home data dir
var dataDir = path.join(config.run.absResultDir, config.dataDir);
fs.mkdirs(dataDir, function(err) {
if (err) throw err;
if (err) {
throw err;
}
cb(err, null);
});
}
@ -236,48 +254,23 @@ function writeConfigurationFile(cb) {
var confFile = path.join(config.run.absResultDir, 'config.json');
fs.writeFile(confFile, JSON.stringify(
config), function(err) {
if (err) log.log('error',"Couldn't write configuration file to disk:"+ confFile + ' ' +err);
if (err) {
log.log('error','Couldnt write configuration file to disk:'+ confFile + ' ' +err);
}
cb(err, null);
});
});
}
function storeSummary(aggregates,cb) {
var summary = path.join(config.run.absResultDir, config.dataDir, 'summary.json');
fs.writeFile(summary, JSON.stringify(aggregates), function(err) {
if(err) {
log.log('error',"Couldn't write summary json file to disk:"+ summary + ' ' +err);
log.log('error','Couldnt write summary json file to disk:'+ summary + ' ' +err);
}
cb();
});
}
function logVersions(cb) {
async.parallel([
function(callback) {
childProcess.execFile(binPath, ['--version'], {
timeout: 120000
}, function(err, stdout, stderr) {
callback(null, stdout);
});
},
function(callback) {
childProcess.exec('java -version', {
timeout: 120000
}, function(err, stdout, stderr) {
callback(null, stderr);
});
}
],
function(err, results) {
log.log('info', 'OS: ' + os.platform() + ' ' + os.release() + ' sitespeed:' + require("../package.json").version +
' ' + ' phantomJs:' + results[0].replace(EOL,'') + ' java:' + results[1].split(EOL)[0]);
cb(null, null);
});
}
Runner.prototype._createOutput = function (downloadErrors, analysisErrors, callBack) {
log.log('info', 'Done analyzing urls');
@ -288,8 +281,9 @@ Runner.prototype._createOutput = function (downloadErrors, analysisErrors, callB
var self = this;
if (this.sites)
if (this.sites) {
this.sites[config.url] = aggregates;
}
/* We got a lot of things to do, lets generate all results
in parallel and then let us know when we are finished
@ -320,17 +314,24 @@ Runner.prototype._createOutput = function (downloadErrors, analysisErrors, callB
renderScreenshots: function(cb) {
if (config.screenshot) {
self.htmlRenderer.renderScreenshots(pages, cb);
} else cb();
} else {
cb();
}
},
sendToGraphite: function(cb) {
if (config.graphiteHost)
if (config.graphiteHost) {
self.graphite.sendPageData(aggregates, pages, cb);
else cb();
} else {
cb();
}
},
renderJUnit: function(cb) {
if (config.junit)
if (config.junit) {
self.junitRenderer.renderAfterFullAnalyse(cb);
else cb();
}
else {
cb();
}
}
},
function(err, results) {
@ -338,12 +339,41 @@ Runner.prototype._createOutput = function (downloadErrors, analysisErrors, callB
// TODO this can be cleaner
// We clear the number of pages tested and
// the collected data, so it is ready for next run
// used when testing multiple sites
// used when testing multiple sites
self.htmlRenderer.numberOfAnalyzedPages = 0;
self.collector.clear();
if (!err)
log.log('info', "Wrote results to " + config.run.absResultDir);
if (!err) {
log.log('info', 'Wrote results to ' + config.run.absResultDir);
}
callBack();
});
};
function logVersions(cb) {
async.parallel([
function(callback) {
childProcess.execFile(binPath, ['--version'], {
timeout: 120000
}, function(err, stdout, stderr) {
callback(null, stdout);
});
},
function(callback) {
childProcess.exec('java -version', {
timeout: 120000
}, function(err, stdout, stderr) {
callback(null, stderr);
});
}
],
function(err, results) {
log.log('info', 'OS: ' + os.platform() + ' ' + os.release() + ' sitespeed:' + require('../package.json').version +
' ' + ' phantomJs:' + results[0].replace(EOL,'') + ' java:' + results[1].split(EOL)[0]);
cb(null, null);
});
}
module.exports = Runner;

View File

@ -28,8 +28,8 @@ module.exports = {
var response = comp.headers.response;
for (var headerName in response) {
if (! response.hasOwnProperty(headerName))
continue;
if (!response.hasOwnProperty(headerName))
continue;
// Cache-control always wins before Expires
// in the HTTP spec
@ -99,8 +99,9 @@ module.exports = {
var lastModifiedDate;
var response = comp.headers.response;
for (var headerName in response) {
if (! response.hasOwnProperty(headerName))
if (! response.hasOwnProperty(headerName)) {
continue;
}
if ('last-modified' === headerName.toLowerCase()) {
lastModifiedDate = new Date(response[headerName]);
@ -110,8 +111,9 @@ module.exports = {
}
// TODO how do we define this?
if (!lastModifiedDate)
if (!lastModifiedDate) {
return -1;
}
return (now.getTime() - lastModifiedDate.getTime()) / 1000;
},
@ -123,34 +125,39 @@ module.exports = {
*/
prettyPrintSeconds: function(seconds) {
if (seconds === -1) return -1;
if (seconds === -1) {
return -1;
}
var secondsPerYear = 365 * 24 * 60 * 60,
secondsPerWeek = 60 * 60 * 24 * 7,
secondsPerDay = 60 * 60 * 24,
secondsPerHour = 60 * 60,
secondsPerMinute = 60,
sign = (seconds < 0) ? "-" : "";
sign = (seconds < 0) ? '-' : '';
if (seconds < 0)
if (seconds < 0) {
seconds = Math.abs(seconds);
}
if (seconds / secondsPerYear >= 1)
return sign + Math.round(seconds / secondsPerYear) + " year" + ((Math.round(
seconds / secondsPerYear) > 1) ? "s" : "");
else if (seconds / secondsPerWeek >= 1)
return sign + Math.round(seconds / secondsPerWeek) + " week" + ((Math.round(
seconds / secondsPerWeek) > 1) ? "s" : "");
else if (seconds / secondsPerDay >= 1)
return sign + Math.round(seconds / secondsPerDay) + " day" + ((Math.round(
seconds / secondsPerDay) > 1) ? "s" : "");
else if (seconds / secondsPerHour >= 1)
return sign + Math.round(seconds / secondsPerHour) + " hour" + ((Math.round(
seconds / secondsPerHour) > 1) ? "s" : "");
else if (seconds / secondsPerMinute >= 1)
return sign + Math.round(seconds / secondsPerMinute) + " minute" + ((
Math.round(seconds / secondsPerMinute) > 1) ? "s" : "");
else return sign + seconds + " second" + ((seconds > 1 || seconds === 0) ? "s" : "");
if (seconds / secondsPerYear >= 1) {
return sign + Math.round(seconds / secondsPerYear) + ' year' + ((Math.round(
seconds / secondsPerYear) > 1) ? 's' : '');
} else if (seconds / secondsPerWeek >= 1) {
return sign + Math.round(seconds / secondsPerWeek) + ' week' + ((Math.round(
seconds / secondsPerWeek) > 1) ? 's' : '');
} else if (seconds / secondsPerDay >= 1) {
return sign + Math.round(seconds / secondsPerDay) + ' day' + ((Math.round(
seconds / secondsPerDay) > 1) ? 's' : '');
} else if (seconds / secondsPerHour >= 1) {
return sign + Math.round(seconds / secondsPerHour) + ' hour' + ((Math.round(
seconds / secondsPerHour) > 1) ? 's' : '');
} else if (seconds / secondsPerMinute >= 1) {
return sign + Math.round(seconds / secondsPerMinute) + ' minute' + ((
Math.round(seconds / secondsPerMinute) > 1) ? 's' : '');
} else {
return sign + seconds + ' second' + ((seconds > 1 || seconds === 0) ? 's' : '');
}
},
/**
@ -159,13 +166,18 @@ module.exports = {
* add ms to milliseconds and turn bytes into kiloytes.
*/
getHumanReadable: function(data, value, showUnit) {
if (data.unit === 'seconds')
if (data.unit === 'seconds') {
return this.prettyPrintSeconds(value);
else if (data.unit === 'milliseconds')
}
else if (data.unit === 'milliseconds') {
return value + (showUnit ? ' ms':'');
else if (data.unit === 'bytes')
}
else if (data.unit === 'bytes') {
return this.getKbSize(value, showUnit);
else return value;
}
else {
return value;
}
},
/**
@ -176,17 +188,21 @@ module.exports = {
if (config.rules[rule]) {
var diff = config.rules[rule].warning - config.rules[rule].error;
if (diff > 0) {
if (value>config.rules[rule].warning)
if (value>config.rules[rule].warning) {
return 'success';
else if (value>config.rules[rule].error)
}
else if (value>config.rules[rule].error) {
return 'warning';
}
return 'danger';
}
else {
if (value<config.rules[rule].warning)
if (value<config.rules[rule].warning) {
return 'success';
else if (value<config.rules[rule].error)
}
else if (value<config.rules[rule].error) {
return 'warning';
}
return 'danger';
}
@ -200,7 +216,7 @@ module.exports = {
**/
getSize: function(components) {
return components.filter(function(comp) {
return comp.size != '-1';
return comp.size !== '-1';
}).reduce(function(sum, comp) {
return sum + comp.size;
}, 0);
@ -212,11 +228,12 @@ module.exports = {
*/
getKbSize: function(size, showUnit) {
// if we don't have any values in the stats
if (isNaN(size))
if (isNaN(size)) {
return 0 + ' kb';
}
var remainder = size % (size > 100 ? 100 : 10);
size -= remainder;
return parseFloat(size / 1000) + (0 === (size % 1000) ? ".0" : "") + (showUnit?' kb':'');
return parseFloat(size / 1000) + (0 === (size % 1000) ? '.0' : '') + (showUnit?' kb':'');
},
select: function(object, keyPath, defaultValue) {
@ -241,7 +258,7 @@ module.exports = {
var urlComponents = url.parse(u);
var hash = crypto.createHash('md5').update(u).digest('hex').substr(0, 7);
var name = urlComponents.pathname;
if (name == '/') {
if (name === '/') {
name = urlComponents.hostname;
} else {
name = name.replace(/^\/|\/$/g, '').split('/').pop();
@ -294,17 +311,17 @@ module.exports = {
timingMetricsDefinition: {
"firstPaintTime": "This is when the first paint happens on the screen, reported by the browser.",
"serverConnectionTime": 'How long time it takes to connect to the server. Definition: connectEnd - connectStart',
"domainLookupTime": 'The time it takes to do the DNS lookup. Definition: domainLookupEnd - domainLookupStart',
"pageLoadTime": 'The time it takes for page to load, from initiation of the pageview (e.g., click on a page link) to load completion in the browser. Important: this is only relevant to some pages, depending on how you page is built. Definition: loadEventStart - navigationStart',
"pageDownloadTime":'How long time does it take to download the page (the HTML). Definition: responseEnd - responseStart',
"serverResponseTime": 'How long time does it take until the server respond. Definition: responseStart - requestStart',
"domContentLoadedTime": "The time the browser takes to parse the document and execute deferred and parser-inserted scripts including the network time from the user's location to your server. Definition: domContentLoadedEventStart - navigationStart",
"domInteractiveTime": "The time the browser takes to parse the document, including the network time from the user's location to your server. Definition: domInteractive - navigationStart",
"redirectionTime": "Time spent on redirects. Definition: fetchStart - navigationStart",
"backEndTime": 'The time it takes for the network and the server to generate and start sending the HTML. Definition: responseStart - navigationStart',
"frontEndTime": 'The time it takes for the browser to parse and create the page. Definition: loadEventStart - responseEnd'
'firstPaintTime': 'This is when the first paint happens on the screen, reported by the browser.',
'serverConnectionTime': 'How long time it takes to connect to the server. Definition: connectEnd - connectStart',
'domainLookupTime': 'The time it takes to do the DNS lookup. Definition: domainLookupEnd - domainLookupStart',
'pageLoadTime': 'The time it takes for page to load, from initiation of the pageview (e.g., click on a page link) to load completion in the browser. Important: this is only relevant to some pages, depending on how you page is built. Definition: loadEventStart - navigationStart',
'pageDownloadTime':'How long time does it take to download the page (the HTML). Definition: responseEnd - responseStart',
'serverResponseTime': 'How long time does it take until the server respond. Definition: responseStart - requestStart',
'domContentLoadedTime': 'The time the browser takes to parse the document and execute deferred and parser-inserted scripts including the network time from the users location to your server. Definition: domContentLoadedEventStart - navigationStart',
'domInteractiveTime': 'The time the browser takes to parse the document, including the network time from the users location to your server. Definition: domInteractive - navigationStart',
'redirectionTime': 'Time spent on redirects. Definition: fetchStart - navigationStart',
'backEndTime': 'The time it takes for the network and the server to generate and start sending the HTML. Definition: responseStart - navigationStart',
'frontEndTime': 'The time it takes for the browser to parse and create the page. Definition: loadEventStart - responseEnd'
},
/**
@ -385,43 +402,57 @@ module.exports = {
} else if (args.length === 3) {
return text.replace('$1', args[0].value).replace('$2', args[1].value).replace(
'$3', args[2].value);
} else return text;
} else {
return text;
}
},
/**
* Get the URL from pageData.
*/
getURLFromPageData: function(pageData) {
if (pageData.yslow)
if (pageData.yslow) {
return pageData.yslow.originalUrl;
else if (pageData.browsertime)
}
else if (pageData.browsertime) {
return pageData.browsertime[0].pageData.url;
else if (pageData.gpsi)
}
else if (pageData.gpsi) {
return pageData.gpsi.id;
else if (pageData.webpagetest)
}
else if (pageData.webpagetest) {
return pageData.webpagetest.response.data.testUrl;
}
return 'undefined';
},
getGraphiteURLKey: function(theUrl) {
myUrl = url.parse(theUrl);
var myUrl = url.parse(theUrl);
var protocol = myUrl.protocol.replace(':', '');
var hostname = myUrl.hostname;
var path = myUrl.pathname;
if (path.indexOf(".") > -1) path = path.replace(".", "_");
if (path.indexOf("~") > -1) path = path.replace("~", "_");
if (path.indexOf('.') > -1) {
path = path.replace('.', '_');
}
if (path.indexOf('~') > -1) {
path = path.replace('~', '_');
}
if (path === '' || path === '/')
if (path === '' || path === '/') {
return protocol + '.' + hostname + '.slash.';
}
var key = protocol + '.' + hostname + '.' + path.replace('/', '.');
if (key.indexOf('.', key.length - 1) !== -1)
if (key.indexOf('.', key.length - 1) !== -1) {
return key;
else return key + '.';
}
else {
return key + '.';
}
}