Skip to content

Commit

Permalink
Performance: Add performance test suite for comparing other frameworks
Browse files Browse the repository at this point in the history
  • Loading branch information
arschmitz committed Mar 5, 2015
1 parent edc154d commit cf4093a
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -6,5 +6,6 @@ style.css
# Folders
bower_components/
node_modules/
external/
icons/svg-min/
.sass-cache/
116 changes: 112 additions & 4 deletions Gruntfile.js
@@ -1,6 +1,8 @@
module.exports = function( grunt ) {

grunt.loadNpmTasks( "grunt-contrib-jshint" );
grunt.loadNpmTasks( "grunt-contrib-connect" );
grunt.loadNpmTasks( "grunt-selenium-server" );
grunt.loadNpmTasks( "grunt-html" );
grunt.loadNpmTasks( "grunt-jscs" );
grunt.loadNpmTasks( "grunt-svgmin" );
Expand All @@ -9,15 +11,46 @@ grunt.loadNpmTasks( "grunt-sass" );
grunt.loadNpmTasks( "grunt-autoprefixer" );
grunt.loadNpmTasks( "grunt-contrib-watch" );

var target,
template = require( "ejs-template" ),
urlParser = require( "url" ),
componentGenerator = require( "./performance/component.js" ),
seleniumChildProcesses = {};

// This saves the process so we can attempt to kill it later in the case of a failure
grunt.event.on( "selenium.start", function( target, process ) {
grunt.log.ok( "Saw process for target: " + target );
seleniumChildProcesses[ target ] = process;
});

// This trys to gracefully handle failures and kill the selenium server but its not 100%
// if this does is not successfull the task will not run again until this has been killed
grunt.util.hooker.hook( grunt.fail, function() {

// Clean up selenium if we left it running after a failure.
grunt.log.writeln( "Attempting to clean up running selenium server." );
for ( target in seleniumChildProcesses ) {
grunt.log.ok( "Killing selenium target: " + target );
try {
seleniumChildProcesses[ target ].kill( "SIGTERM" );
}
catch ( e ) {

// This is only if the kill command fails
grunt.log.warn( "Unable to stop selenium target: " + target );
}
}
});

grunt.initConfig({
jshint: {
files: [ "*.js" ],
files: [ "*.js", "performance/*.js", "performance/frameworks/*.js" ],
options: {
jshintrc: ".jshintrc"
}
},
jscs: {
all: [ "*.js" ]
all: [ "*.js", "performance/*.js", "performance/frameworks/*.js" ]
},

// Minifies SVGs
Expand Down Expand Up @@ -109,9 +142,84 @@ grunt.initConfig({
spawn: false
}
}
},
perfjankie: {
options: {
suite: "perfSlides - Performance Analysis"
},
"comparison": {
options: {
repeat: 2,
selenium: "http://localhost:4444/wd/hub",
browsers: "chrome",
couch: {
server: "http://localhost:5984",
database: "css-performance",
updateSite: true
},
urls: [
"http://localhost:4200/framework/foundation/component/button/count/1000/" +
"foundation:button",
"http://localhost:4200/framework/jquery-mobile/component/button/count/1000/" +
"jquery-mobile:button",
"http://localhost:4200/framework/jquery-ui/component/button/count/1000/" +
"jquery-ui:button",
"http://localhost:4200/framework/bootstrap/component/button/count/1000/" +
"bootstrap:button"
]
}
}
},
connect: {
options: {
port: 4200,
base: ".",
middleware: [
template.middleware({ basedir: __dirname }),
function( req, res ) {
var data, i,
url = urlParser.parse( req.url, true ),
query = {},
parts = url.pathname.split( "/" ),
file = req.url.replace( /^\//, "" ).split( "?" )[ 0 ];

for ( i = 1; i < parts.length; i += 2 ) {
query[ parts[ i ] ] = parts[ i + 1 ];
}
if ( file.split( "." ).length <= 1 ) {
data = componentGenerator.generate(
query.framework,
query.component,
query.count
);
file = "performance/component.html";
}
res.endTemplate( file, data );
}
]
},
perf: {},
dev: {
options: {
keepalive: true
}
}
},
"start-selenium-server": {
dev: {
options: {
downloadUrl: "https://selenium-release.storage.googleapis.com/2.40/" +
"selenium-server-standalone-2.40.0.jar",
downloadLocation: "external/selenium",
serverOptions: {
"Dwebdriver.chrome.driver=node_modules/chromedriver/bin/chromedriver": ""
},
systemProperties: {}
}
}
}
});

grunt.loadNpmTasks( "perfjankie" );
grunt.registerTask( "update-authors", function() {
var getAuthors = require( "grunt-git-authors" ),
done = this.async();
Expand All @@ -131,5 +239,5 @@ grunt.registerTask( "update-authors", function() {

grunt.registerTask( "default", [ "jshint", "jscs" ] );
grunt.registerTask( "build", [ "sass", "autoprefixer" ] );

grunt.registerTask( "perf", [ "start-selenium-server", "connect:perf", "perfjankie" ] );
};
17 changes: 12 additions & 5 deletions package.json
Expand Up @@ -43,15 +43,22 @@
"dependencies": {},
"devDependencies": {
"commitplease": "2.0.0",
"grunt": "^0.4.5",
"chromedriver": "2.13.0",
"commitplease": "2.0.0",
"ejs-template": "0.1.0",
"grunt": "0.4.5",
"grunt-autoprefixer": "^2.1.0",
"grunt-contrib-jshint": "0.10.0",
"grunt-contrib-jshint": "0.10.0",
"grunt-contrib-connect": "0.9.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-git-authors": "2.0.0",
"grunt-jscs": "0.6.2",
"grunt-sass": "^0.17.0",
"grunt-selenium-server": "0.1.2",
"grunt-svgmin": "^2.0.0",
"grunt-svgstore": "^0.5.0",
"grunt-sass": "^0.17.0"
},
"keywords": []
"grunt-html": "1.6.0",
"perfjankie": "1.1.1"
},
"keywords": []
}
20 changes: 20 additions & 0 deletions performance/component.html
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<%
var stylesheets = "";
css.forEach(function( value ){
stylesheets += "<link rel='stylesheet' href='" + value + "'>";
});
%>
<%- stylesheets %>
</head>
<body>
<h1><%= title %></h1>
<h2>Component Count: <%= count %></h2>
<%- html %>
</body>
</html>
33 changes: 33 additions & 0 deletions performance/component.js
@@ -0,0 +1,33 @@
var components = {
generate: function( frameworkName, component, count ) {
var currentCount = 0,
framework = require( "./frameworks/" + frameworkName + ".js" ),
keys = Object.keys( framework[ component ].variations ),
current = {},
html = "";

function render( i ) {
framework[ component ].variations[ keys[ i ] ].forEach(function( value ) {
current[ keys[ i ] ] = value;
if ( i < keys.length - 1 ) {
render( i + 1 );
} else {
if ( currentCount < count ) {
currentCount++;
html = html + framework[ component ].generator.call( this, current );
}
}
});
}
while ( currentCount < count ) {
render( 0 );
}
return {
html: html,
count: currentCount,
css: framework.css,
title: frameworkName + ": " + component
};
}
};
module.exports = components;
38 changes: 38 additions & 0 deletions performance/frameworks/bootstrap.js
@@ -0,0 +1,38 @@
module.exports = {
css: [ "//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" ],
button: {
generator: function( options ) {
var button = "<button class='btn " + options.state + " " + options.size + "' >";
if ( options.icon ) {
button = button + "<span class='glyphicon glyphicon-" + options.icon +
"'></span>";
}
return button + " Button </button>";
},
variations: {
state: [
"btn-default",
"btn-primary",
"btn-success",
"btn-info",
"btn-warning",
"btn-danger",
"btn-link"
],
size: [
"",
"btn-lg",
"btn-sm",
"btn-xs"
],
icon: [
false,
"astrisk",
"plus",
"minus",
"euro",
"fire"
]
}
}
};
47 changes: 47 additions & 0 deletions performance/frameworks/foundation.js
@@ -0,0 +1,47 @@
module.exports = {
css: [
"//cdn.foundation5.zurb.com/foundation.css",
"//cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.eot",
"https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.min.css"
],
button: {
generator: function( options ) {
var button = "<button class='button" + options.state + options.size + options.shape +
"' >";
if ( options.icon ) {
button = button + "<i class='fi-" + options.icon +
"'></i>";
}
return button + " Button </button>";
},
variations: {
state: [
"",
" secondary",
" alert",
" info",
" disabled",
" success"
],
size: [
"",
" tiny",
" small",
" large"
],
shape: [
" round",
" radius",
" expand"
],
icon: [
false,
"compas",
"power",
"crown",
"skull",
"map"
]
}
}
};
45 changes: 45 additions & 0 deletions performance/frameworks/jquery-mobile.js
@@ -0,0 +1,45 @@
module.exports = {
css: [ "//code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" ],
button: {
generator: function( options ) {
var position = ( options.icon === "" ) ? "" : options.iconPosition;
return "<button class='ui-btn" +
options.options +
options.theme +
position +
options.icon +
"'>Button</button>";
},
variations: {
theme: [
" ui-btn-a",
" ui-btn-b",
" ui-state-disabled ui-btn-a",
" ui-state-disabled ui-btn-b"
],
options: [
" ui-btn-inline ui-mini",
" ui-btn-inline ui-corner-all",
" ui-btn-inline ui-shadow",
" ui-btn-inline",
" ui-corner-all ui-shadow",
" ui-corner-all ui-shadow ui-btn-inline",
" ui-corner-all ui-shadow ui-mini ui-btn-inline"
],
iconPosition: [
" ui-btn-icon-left",
" ui-btn-icon-top",
" ui-btn-icon-bottom",
" ui-btn-icon-right"
],
icon: [
"",
" ui-icon ui-icon-bars",
" ui-icon ui-icon-bullets",
" ui-icon ui-icon-camera",
" ui-icon ui-icon-audio",
" ui-icon ui-icon-cloud"
]
}
}
};

0 comments on commit cf4093a

Please sign in to comment.