aligning to new bt
This commit is contained in:
parent
b1e39874b8
commit
357f96ff9c
|
|
@ -7,273 +7,275 @@
|
|||
'use strict';
|
||||
|
||||
var util = require('../util/util'),
|
||||
yslowUtil = require('../util/yslowUtil');
|
||||
yslowUtil = require('../util/yslowUtil');
|
||||
|
||||
var pages = [];
|
||||
var isDoc = function(comp) {
|
||||
return (comp.type === 'doc');
|
||||
return (comp.type === 'doc');
|
||||
};
|
||||
|
||||
exports.processPage = function(pageData) {
|
||||
|
||||
var p = {};
|
||||
var p = {};
|
||||
|
||||
if (pageData.yslow) {
|
||||
p = collectYSlowMetrics(pageData, p);
|
||||
collectYSlowRules(pageData, p);
|
||||
}
|
||||
if (pageData.yslow) {
|
||||
p = collectYSlowMetrics(pageData, p);
|
||||
collectYSlowRules(pageData, p);
|
||||
}
|
||||
|
||||
if (pageData.gpsi) {
|
||||
collectGPSI(pageData, p);
|
||||
}
|
||||
if (pageData.gpsi) {
|
||||
collectGPSI(pageData, p);
|
||||
}
|
||||
|
||||
if (pageData.browsertime) {
|
||||
collectBrowserTime(pageData, p);
|
||||
collectHAR(pageData, p);
|
||||
}
|
||||
if (pageData.webpagetest) {
|
||||
collectWPT(pageData, p);
|
||||
}
|
||||
if (pageData.headless) {
|
||||
collectHeadlessData(pageData, p);
|
||||
}
|
||||
if (pageData.browsertime) {
|
||||
collectBrowserTime(pageData, p);
|
||||
collectHAR(pageData, p);
|
||||
}
|
||||
if (pageData.webpagetest) {
|
||||
collectWPT(pageData, p);
|
||||
}
|
||||
if (pageData.headless) {
|
||||
collectHeadlessData(pageData, p);
|
||||
}
|
||||
|
||||
p.url = util.getURLFromPageData(pageData);
|
||||
p.url = util.getURLFromPageData(pageData);
|
||||
|
||||
// TODO fix a cleaner check for this
|
||||
// if an analyzed failed, skip it
|
||||
if (p.url !== 'undefined') {
|
||||
pages.push(p);
|
||||
}
|
||||
// TODO fix a cleaner check for this
|
||||
// if an analyzed failed, skip it
|
||||
if (p.url !== 'undefined') {
|
||||
pages.push(p);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function collectYSlowMetrics(pageData, p) {
|
||||
|
||||
var docs = pageData.yslow.comps.filter(isDoc);
|
||||
var docs = pageData.yslow.comps.filter(isDoc);
|
||||
|
||||
var assetTypes = ['js', 'css', 'image', 'cssimage', 'font', 'flash', 'iframe', 'doc'];
|
||||
var assetTypes = ['js', 'css', 'image', 'cssimage', 'font', 'flash', 'iframe', 'doc'];
|
||||
|
||||
docs.forEach(function(doc) {
|
||||
p = {
|
||||
score: pageData.yslow.o,
|
||||
// strip to only store response headers to save space?
|
||||
headers: doc.headers,
|
||||
yslow: {
|
||||
requests: {
|
||||
'v': pageData.yslow.comps.length,
|
||||
'unit': ''
|
||||
},
|
||||
requestsMissingExpire: {
|
||||
'v': pageData.yslow.comps.filter(function(c) {
|
||||
return yslowUtil.getCacheTime(c) === 0;
|
||||
}).length,
|
||||
'unit': ''
|
||||
},
|
||||
timeSinceLastModification: {
|
||||
'v': yslowUtil.getTimeSinceLastMod(doc),
|
||||
'unit': 'seconds'
|
||||
},
|
||||
cacheTime: {
|
||||
'v': yslowUtil.getCacheTime(doc),
|
||||
'unit': 'seconds'
|
||||
},
|
||||
docWeight: {
|
||||
'v': doc.size,
|
||||
'unit': 'bytes'
|
||||
},
|
||||
pageWeight: {
|
||||
'v': yslowUtil.getSize(pageData.yslow.comps),
|
||||
'unit': 'bytes'
|
||||
}
|
||||
}
|
||||
};
|
||||
p.yslow.assets = {};
|
||||
assetTypes.forEach(function(asset) {
|
||||
p.yslow.assets[asset] = {
|
||||
'v': pageData.yslow.comps.filter(function(c) {
|
||||
return c.type === asset;
|
||||
}).length,
|
||||
'unit': ''
|
||||
};
|
||||
p.yslow.assets[asset + 'Weight'] = {
|
||||
'v': yslowUtil.getSize(pageData.yslow.comps.filter(function(c) {
|
||||
return c.type === asset;
|
||||
})),
|
||||
'unit': 'bytes'
|
||||
};
|
||||
});
|
||||
});
|
||||
return p;
|
||||
docs.forEach(function(doc) {
|
||||
p = {
|
||||
score: pageData.yslow.o,
|
||||
// strip to only store response headers to save space?
|
||||
headers: doc.headers,
|
||||
yslow: {
|
||||
requests: {
|
||||
'v': pageData.yslow.comps.length,
|
||||
'unit': ''
|
||||
},
|
||||
requestsMissingExpire: {
|
||||
'v': pageData.yslow.comps.filter(function(c) {
|
||||
return yslowUtil.getCacheTime(c) === 0;
|
||||
}).length,
|
||||
'unit': ''
|
||||
},
|
||||
timeSinceLastModification: {
|
||||
'v': yslowUtil.getTimeSinceLastMod(doc),
|
||||
'unit': 'seconds'
|
||||
},
|
||||
cacheTime: {
|
||||
'v': yslowUtil.getCacheTime(doc),
|
||||
'unit': 'seconds'
|
||||
},
|
||||
docWeight: {
|
||||
'v': doc.size,
|
||||
'unit': 'bytes'
|
||||
},
|
||||
pageWeight: {
|
||||
'v': yslowUtil.getSize(pageData.yslow.comps),
|
||||
'unit': 'bytes'
|
||||
}
|
||||
}
|
||||
};
|
||||
p.yslow.assets = {};
|
||||
assetTypes.forEach(function(asset) {
|
||||
p.yslow.assets[asset] = {
|
||||
'v': pageData.yslow.comps.filter(function(c) {
|
||||
return c.type === asset;
|
||||
}).length,
|
||||
'unit': ''
|
||||
};
|
||||
p.yslow.assets[asset + 'Weight'] = {
|
||||
'v': yslowUtil.getSize(pageData.yslow.comps.filter(function(c) {
|
||||
return c.type === asset;
|
||||
})),
|
||||
'unit': 'bytes'
|
||||
};
|
||||
});
|
||||
});
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
function collectYSlowRules(pageData, p) {
|
||||
p.rules = {};
|
||||
// add all rule scores as fields
|
||||
Object.keys(pageData.yslow.g).forEach(function(rule) {
|
||||
p.rules[rule] = {
|
||||
'v': pageData.yslow.g[rule].score,
|
||||
'unit': ''
|
||||
};
|
||||
// TODO how should we name them
|
||||
p.rules[rule].items = {
|
||||
'v': pageData.yslow.g[rule].components.length,
|
||||
'unit': ''
|
||||
};
|
||||
});
|
||||
p.rules = {};
|
||||
// add all rule scores as fields
|
||||
Object.keys(pageData.yslow.g).forEach(function(rule) {
|
||||
p.rules[rule] = {
|
||||
'v': pageData.yslow.g[rule].score,
|
||||
'unit': ''
|
||||
};
|
||||
// TODO how should we name them
|
||||
p.rules[rule].items = {
|
||||
'v': pageData.yslow.g[rule].components.length,
|
||||
'unit': ''
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function collectGPSI(pageData, p) {
|
||||
p.gpsi = {};
|
||||
p.gpsi.gscore = {
|
||||
'v': pageData.gpsi.score,
|
||||
'unit': ''
|
||||
};
|
||||
p.gpsi = {};
|
||||
p.gpsi.gscore = {
|
||||
'v': pageData.gpsi.score,
|
||||
'unit': ''
|
||||
};
|
||||
}
|
||||
|
||||
function collectHeadlessData(pageData, p) {
|
||||
var timingsWeWillPush = ['min', 'mean', 'median', 'p90', 'p99', 'max'];
|
||||
p.headless = {};
|
||||
pageData.headless.getStats().forEach(function(timing) {
|
||||
p.headless[timing.id] = {};
|
||||
timingsWeWillPush.forEach(function(number) {
|
||||
p.headless[timing.id][number] = {
|
||||
'v': timing.stats[number],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
});
|
||||
});
|
||||
var timingsWeWillPush = ['min', 'mean', 'median', 'p90', 'p99', 'max'];
|
||||
p.headless = {};
|
||||
pageData.headless.getStats().forEach(function(timing) {
|
||||
p.headless[timing.id] = {};
|
||||
timingsWeWillPush.forEach(function(number) {
|
||||
p.headless[timing.id][number] = {
|
||||
'v': timing.stats[number],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function collectHAR(pageData, p) {
|
||||
p.har = [];
|
||||
if (pageData.browsertime) {
|
||||
Array.prototype.push.apply(p.har, pageData.browsertime.har);
|
||||
}
|
||||
p.har = [];
|
||||
if (pageData.browsertime) {
|
||||
Array.prototype.push.apply(p.har, pageData.browsertime.har);
|
||||
}
|
||||
}
|
||||
|
||||
function collectWPT(pageData, p) {
|
||||
p.wpt = {};
|
||||
p.wpt = {};
|
||||
|
||||
// the views we will test, we will add the repeated view later if we have it
|
||||
var views = ['firstView'];
|
||||
// the views we will test, we will add the repeated view later if we have it
|
||||
var views = ['firstView'];
|
||||
|
||||
// the different kind of data that we will fetch from WPT and add to the page
|
||||
var sizes = ['image_savings', 'image_total', 'bytesIn', 'bytesInDoc'];
|
||||
var timings = ['SpeedIndex', 'firstPaint', 'render', 'TTFB', 'visualComplete', 'domContentLoadedEventEnd', 'loadTime'];
|
||||
var others = ['requests'];
|
||||
// the different kind of data that we will fetch from WPT and add to the page
|
||||
var sizes = ['image_savings', 'image_total', 'bytesIn', 'bytesInDoc'];
|
||||
var timings = ['SpeedIndex', 'firstPaint', 'render', 'TTFB', 'visualComplete', 'domContentLoadedEventEnd',
|
||||
'loadTime'
|
||||
];
|
||||
var others = ['requests'];
|
||||
|
||||
// for all browsers/locations and connections
|
||||
pageData.webpagetest.wpt.forEach(function(browserAndLocation) {
|
||||
// for all browsers/locations and connections
|
||||
pageData.webpagetest.wpt.forEach(function(browserAndLocation) {
|
||||
|
||||
var connectivity = browserAndLocation.response.data.connectivity.toLowerCase();
|
||||
var locationAndBrowser = browserAndLocation.response.data.location.split(':');
|
||||
var location = locationAndBrowser[0].toLowerCase();
|
||||
var browser = locationAndBrowser[1].toLowerCase();
|
||||
var connectivity = browserAndLocation.response.data.connectivity.toLowerCase();
|
||||
var locationAndBrowser = browserAndLocation.response.data.location.split(':');
|
||||
var location = locationAndBrowser[0].toLowerCase();
|
||||
var browser = locationAndBrowser[1].toLowerCase();
|
||||
|
||||
// if we don't have it, setup a clean object
|
||||
p.wpt[location] = p.wpt[location] || {};
|
||||
p.wpt[location][browser] = p.wpt[location][browser] || {};
|
||||
p.wpt[location][browser][connectivity] = p.wpt[location][browser][connectivity] || {};
|
||||
// if we don't have it, setup a clean object
|
||||
p.wpt[location] = p.wpt[location] || {};
|
||||
p.wpt[location][browser] = p.wpt[location][browser] || {};
|
||||
p.wpt[location][browser][connectivity] = p.wpt[location][browser][connectivity] || {};
|
||||
|
||||
// only collect repeat view when we have the data
|
||||
if (browserAndLocation.response.data.median.repeatView) {
|
||||
views.push('repeatView');
|
||||
}
|
||||
// only collect repeat view when we have the data
|
||||
if (browserAndLocation.response.data.median.repeatView) {
|
||||
views.push('repeatView');
|
||||
}
|
||||
|
||||
views.forEach(function(view) {
|
||||
p.wpt[location][browser][connectivity][view] = {};
|
||||
sizes.forEach(function(size) {
|
||||
p.wpt[location][browser][connectivity][view][size] = {
|
||||
'v': browserAndLocation.response.data.median[view][size],
|
||||
'unit': 'bytes'
|
||||
};
|
||||
});
|
||||
timings.forEach(function(timing) {
|
||||
p.wpt[location][browser][connectivity][view][timing] = {
|
||||
'v': browserAndLocation.response.data.median[view][timing],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
});
|
||||
views.forEach(function(view) {
|
||||
p.wpt[location][browser][connectivity][view] = {};
|
||||
sizes.forEach(function(size) {
|
||||
p.wpt[location][browser][connectivity][view][size] = {
|
||||
'v': browserAndLocation.response.data.median[view][size],
|
||||
'unit': 'bytes'
|
||||
};
|
||||
});
|
||||
timings.forEach(function(timing) {
|
||||
p.wpt[location][browser][connectivity][view][timing] = {
|
||||
'v': browserAndLocation.response.data.median[view][timing],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
});
|
||||
|
||||
// also fetch all user timings!
|
||||
var userTimings = browserAndLocation.response.data.median[view].userTimes;
|
||||
if (userTimings) {
|
||||
Object.keys(userTimings).forEach(function(userTiming) {
|
||||
p.wpt[location][browser][connectivity][view][userTiming] = {
|
||||
'v': browserAndLocation.response.data.median[view].userTimes[userTiming],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
});
|
||||
}
|
||||
// also fetch all user timings!
|
||||
var userTimings = browserAndLocation.response.data.median[view].userTimes;
|
||||
if (userTimings) {
|
||||
Object.keys(userTimings).forEach(function(userTiming) {
|
||||
p.wpt[location][browser][connectivity][view][userTiming] = {
|
||||
'v': browserAndLocation.response.data.median[view].userTimes[userTiming],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
others.forEach(function(metric) {
|
||||
p.wpt[location][browser][connectivity][view][metric] = {
|
||||
'v': browserAndLocation.response.data.median[view][metric],
|
||||
'unit': ''
|
||||
};
|
||||
});
|
||||
others.forEach(function(metric) {
|
||||
p.wpt[location][browser][connectivity][view][metric] = {
|
||||
'v': browserAndLocation.response.data.median[view][metric],
|
||||
'unit': ''
|
||||
};
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function collectBrowserTime(pageData, p) {
|
||||
|
||||
var types = ['default', 'custom'];
|
||||
var types = ['default', 'custom'];
|
||||
|
||||
var statsWeWillPush = ['min', 'mean', 'median', 'p90', 'p99', 'max'];
|
||||
p.timings = {};
|
||||
p.extras = {};
|
||||
p.custom = {};
|
||||
var statsWeWillPush = ['min', 'mean', 'median', 'p90', 'p99', 'max'];
|
||||
p.timings = {};
|
||||
p.extras = {};
|
||||
p.custom = {};
|
||||
|
||||
types.forEach(function(type) {
|
||||
types.forEach(function(type) {
|
||||
|
||||
pageData.browsertime.browsertime.forEach(function(runPerBrowser) {
|
||||
var browser = runPerBrowser.browserName;
|
||||
p.timings[browser] = p.timings[browser] || {};
|
||||
p.extras[browser] = p.extras[browser] || {};
|
||||
p.custom[browser] = p.custom[browser] || {};
|
||||
pageData.browsertime.browsertime.forEach(function(runPerBrowser) {
|
||||
var browser = runPerBrowser.browserName;
|
||||
p.timings[browser] = p.timings[browser] || {};
|
||||
p.extras[browser] = p.extras[browser] || {};
|
||||
p.custom[browser] = p.custom[browser] || {};
|
||||
|
||||
runPerBrowser[type].statistics.forEach(function(stats) {
|
||||
var a = p.custom;
|
||||
if (type === 'default') {
|
||||
for (var stats in runPerBrowser[type].statistics) {
|
||||
var a = p.custom;
|
||||
if (type === 'default') {
|
||||
|
||||
// if it is a timing
|
||||
if (stats.name.indexOf('Time') > -1 || stats.name === 'speedIndex' || stats.name === 'firstPaint') {
|
||||
a = p.timings;
|
||||
} else {
|
||||
a = p.extras;
|
||||
}
|
||||
}
|
||||
a[browser][stats.name] = {};
|
||||
a[stats.name] = {};
|
||||
statsWeWillPush.forEach(function(number) {
|
||||
a[browser][stats.name][number] = {
|
||||
'v': stats[number],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
a[stats.name][number] = {
|
||||
'v': stats[number],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
// if it is a timing
|
||||
if (stats.indexOf('Time') > -1 || stats === 'speedIndex' || stats === 'firstPaint') {
|
||||
a = p.timings;
|
||||
} else {
|
||||
a = p.extras;
|
||||
}
|
||||
}
|
||||
a[browser][stats] = {};
|
||||
a[stats] = {};
|
||||
for (var number in statsWeWillPush) {
|
||||
a[browser][stats][statsWeWillPush[number]] = {
|
||||
'v': runPerBrowser[type].statistics[stats][statsWeWillPush[number]],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
a[stats][statsWeWillPush[number]] = {
|
||||
'v': runPerBrowser[type].statistics[stats][statsWeWillPush[number]],
|
||||
'unit': 'milliseconds'
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
exports.generateResults = function() {
|
||||
return {
|
||||
id: 'pages',
|
||||
list: pages
|
||||
};
|
||||
return {
|
||||
id: 'pages',
|
||||
list: pages
|
||||
};
|
||||
};
|
||||
|
||||
exports.clear = function() {
|
||||
pages = [];
|
||||
pages = [];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ function waitFor(testFx, onReady, timeOutMillis) {
|
|||
} else {
|
||||
if (!condition) {
|
||||
// If condition still not fulfilled (timeout but condition is 'false')
|
||||
console.log("'waitFor()' timeout");
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
// Condition fulfilled (timeout and/or condition is 'true')
|
||||
|
|
@ -131,7 +130,7 @@ function waitFor(testFx, onReady, timeOutMillis) {
|
|||
|
||||
var page = require('webpage').create(),
|
||||
system = require('system'),
|
||||
address, output, harfilename, w, h, agent, basicauth, auth, headers, fs = require('fs');
|
||||
address, output, harfilename, w, h, agent, basicauth, auth, headers, waitScript, fs = require('fs');
|
||||
|
||||
if (system.args.length < 6 || system.args.length > 9) {
|
||||
console.log('Usage: phantom.js URL filename harfilename width height user-agent headers basic:auth');
|
||||
|
|
@ -145,6 +144,7 @@ if (system.args.length < 6 || system.args.length > 9) {
|
|||
agent = system.args[6];
|
||||
headers = system.args[7];
|
||||
basicauth = system.args[8];
|
||||
waitScript = 'window.performance.timing.loadEventEnd > 0';
|
||||
|
||||
if (basicauth) {
|
||||
auth = basicauth.split(':');
|
||||
|
|
@ -196,15 +196,15 @@ if (system.args.length < 6 || system.args.length > 9) {
|
|||
page.title = page.evaluate(function() {
|
||||
return document.title;
|
||||
});
|
||||
waitFor(function() {
|
||||
// Check in the page if a specific element is now visible
|
||||
var self = this;
|
||||
console.log(waitScript);
|
||||
waitFor(function) {
|
||||
// Check in the page if a specific element is now availible
|
||||
return page.evaluate(function() {
|
||||
return (window.performance.timing.loadEventEnd > 0);
|
||||
return waitScript;
|
||||
});
|
||||
}, function() {
|
||||
var timings = page.evaluate(function() {
|
||||
|
||||
|
||||
var t = window.performance.timing;
|
||||
var marks = '';
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
<tbody>
|
||||
{{#each default.statistics}}
|
||||
<tr>
|
||||
<td>{{name}} <a rel="tooltip" data-placement="right" data-html="false" href="#" data-original-title="{{getTimingMetricsDefinition name}}"><i class="glyphicon glyphicon-question-sign"></i></a></td>
|
||||
<td>{{getDecimals min 1}}</td>
|
||||
<td>{{getDecimals median 1}}</td>
|
||||
<td>{{getDecimals p90 1}}</td>
|
||||
<td>{{getDecimals max 1}}</td>
|
||||
<td>{{@key}} <a rel="tooltip" data-placement="right" data-html="false" href="#" data-original-title="{{getTimingMetricsDefinition name}}"><i class="glyphicon glyphicon-question-sign"></i></a></td>
|
||||
<td>{{getDecimals min 1}}</td>
|
||||
<td>{{getDecimals median 1}}</td>
|
||||
<td>{{getDecimals p90 1}}</td>
|
||||
<td>{{getDecimals max 1}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
|
|
|
|||
Loading…
Reference in New Issue