sitespeed.io/lib/plugins/browsertime/analyzer.js

122 lines
3.4 KiB
JavaScript

'use strict';
const merge = require('lodash.merge');
const forEach = require('lodash.foreach');
const path = require('path');
const browsertime = require('browsertime');
const log = require('intel').getLogger('sitespeedio.plugin.browsertime');
const set = require('lodash.set');
const get = require('lodash.get');
const coach = require('webcoach');
const browserScripts = browsertime.browserScripts;
const defaultBrowsertimeOptions = {
statistics: true
};
const iphone6UserAgent =
'Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 ' +
'(KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25';
async function parseUserScripts(scripts) {
if (!Array.isArray(scripts)) scripts = [scripts];
const allUserScripts = {};
for (let script of scripts) {
const myScript = await browserScripts.findAndParseScripts(
path.resolve(script),
'custom'
);
merge(allUserScripts, myScript);
}
return allUserScripts;
}
async function addCoachScripts(scripts) {
const coachAdvice = await coach.getDomAdvice();
scripts.coach = {
coachAdvice: coachAdvice
};
return scripts;
}
function addExtraScripts(scriptsByCategory, pluginScripts) {
// For all different script in the array
for (let scripts of pluginScripts) {
// and then for all scripts in that category
forEach(scripts.scripts, function(script, name) {
set(scriptsByCategory, scripts.category + '.' + name, script);
});
}
return scriptsByCategory;
}
function setupAsynScripts(asyncScripts) {
var allAsyncScripts = {};
// For all different script in the array
for (var scripts of asyncScripts) {
// and then for all scripts in that category
forEach(scripts.scripts, function(script, name) {
set(allAsyncScripts, scripts.category + '.' + name, script);
});
}
return allAsyncScripts;
}
module.exports = {
async analyzeUrl(url, options, pluginScripts, pluginAsyncScripts) {
const btOptions = merge({}, defaultBrowsertimeOptions, options);
// set mobile options
if (options.mobile) {
btOptions.viewPort = '360x640';
if (btOptions.browser === 'chrome') {
const emulation = get(
btOptions,
'chrome.mobileEmulation.deviceName',
'iPhone 6'
);
btOptions.chrome.mobileEmulation = {
deviceName: emulation
};
} else {
btOptions.userAgent = iphone6UserAgent;
}
}
const scriptCategories = await browserScripts.allScriptCategories;
let scriptsByCategory = await browserScripts.getScriptsForCategories(
scriptCategories
);
if (btOptions.script) {
const userScripts = await parseUserScripts(btOptions.script);
scriptsByCategory = merge(scriptsByCategory, userScripts);
}
if (btOptions.coach) {
scriptsByCategory = addCoachScripts(scriptsByCategory);
}
scriptsByCategory = await addExtraScripts(scriptsByCategory, pluginScripts);
const engine = new browsertime.Engine(btOptions);
log.info(
'Starting %s for analysing %s %s time(s)',
btOptions.browser,
url,
btOptions.iterations
);
const asyncScript =
pluginAsyncScripts.length > 0
? await setupAsynScripts(pluginAsyncScripts)
: undefined;
try {
await engine.start();
const result = await engine.run(url, scriptsByCategory, asyncScript);
return result;
} finally {
await engine.stop();
}
}
};