Skip to content
This repository was archived by the owner on Dec 11, 2021. It is now read-only.

Commit cf4093a

Browse files
committed
Performance: Add performance test suite for comparing other frameworks
Fixes gh-19 Ref gh-2
1 parent edc154d commit cf4093a

File tree

9 files changed

+353
-9
lines changed

9 files changed

+353
-9
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ style.css
66
# Folders
77
bower_components/
88
node_modules/
9+
external/
910
icons/svg-min/
1011
.sass-cache/

Gruntfile.js

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module.exports = function( grunt ) {
22

33
grunt.loadNpmTasks( "grunt-contrib-jshint" );
4+
grunt.loadNpmTasks( "grunt-contrib-connect" );
5+
grunt.loadNpmTasks( "grunt-selenium-server" );
46
grunt.loadNpmTasks( "grunt-html" );
57
grunt.loadNpmTasks( "grunt-jscs" );
68
grunt.loadNpmTasks( "grunt-svgmin" );
@@ -9,15 +11,46 @@ grunt.loadNpmTasks( "grunt-sass" );
911
grunt.loadNpmTasks( "grunt-autoprefixer" );
1012
grunt.loadNpmTasks( "grunt-contrib-watch" );
1113

14+
var target,
15+
template = require( "ejs-template" ),
16+
urlParser = require( "url" ),
17+
componentGenerator = require( "./performance/component.js" ),
18+
seleniumChildProcesses = {};
19+
20+
// This saves the process so we can attempt to kill it later in the case of a failure
21+
grunt.event.on( "selenium.start", function( target, process ) {
22+
grunt.log.ok( "Saw process for target: " + target );
23+
seleniumChildProcesses[ target ] = process;
24+
});
25+
26+
// This trys to gracefully handle failures and kill the selenium server but its not 100%
27+
// if this does is not successfull the task will not run again until this has been killed
28+
grunt.util.hooker.hook( grunt.fail, function() {
29+
30+
// Clean up selenium if we left it running after a failure.
31+
grunt.log.writeln( "Attempting to clean up running selenium server." );
32+
for ( target in seleniumChildProcesses ) {
33+
grunt.log.ok( "Killing selenium target: " + target );
34+
try {
35+
seleniumChildProcesses[ target ].kill( "SIGTERM" );
36+
}
37+
catch ( e ) {
38+
39+
// This is only if the kill command fails
40+
grunt.log.warn( "Unable to stop selenium target: " + target );
41+
}
42+
}
43+
});
44+
1245
grunt.initConfig({
1346
jshint: {
14-
files: [ "*.js" ],
47+
files: [ "*.js", "performance/*.js", "performance/frameworks/*.js" ],
1548
options: {
1649
jshintrc: ".jshintrc"
1750
}
1851
},
1952
jscs: {
20-
all: [ "*.js" ]
53+
all: [ "*.js", "performance/*.js", "performance/frameworks/*.js" ]
2154
},
2255

2356
// Minifies SVGs
@@ -109,9 +142,84 @@ grunt.initConfig({
109142
spawn: false
110143
}
111144
}
145+
},
146+
perfjankie: {
147+
options: {
148+
suite: "perfSlides - Performance Analysis"
149+
},
150+
"comparison": {
151+
options: {
152+
repeat: 2,
153+
selenium: "http://localhost:4444/wd/hub",
154+
browsers: "chrome",
155+
couch: {
156+
server: "http://localhost:5984",
157+
database: "css-performance",
158+
updateSite: true
159+
},
160+
urls: [
161+
"http://localhost:4200/framework/foundation/component/button/count/1000/" +
162+
"foundation:button",
163+
"http://localhost:4200/framework/jquery-mobile/component/button/count/1000/" +
164+
"jquery-mobile:button",
165+
"http://localhost:4200/framework/jquery-ui/component/button/count/1000/" +
166+
"jquery-ui:button",
167+
"http://localhost:4200/framework/bootstrap/component/button/count/1000/" +
168+
"bootstrap:button"
169+
]
170+
}
171+
}
172+
},
173+
connect: {
174+
options: {
175+
port: 4200,
176+
base: ".",
177+
middleware: [
178+
template.middleware({ basedir: __dirname }),
179+
function( req, res ) {
180+
var data, i,
181+
url = urlParser.parse( req.url, true ),
182+
query = {},
183+
parts = url.pathname.split( "/" ),
184+
file = req.url.replace( /^\//, "" ).split( "?" )[ 0 ];
185+
186+
for ( i = 1; i < parts.length; i += 2 ) {
187+
query[ parts[ i ] ] = parts[ i + 1 ];
188+
}
189+
if ( file.split( "." ).length <= 1 ) {
190+
data = componentGenerator.generate(
191+
query.framework,
192+
query.component,
193+
query.count
194+
);
195+
file = "performance/component.html";
196+
}
197+
res.endTemplate( file, data );
198+
}
199+
]
200+
},
201+
perf: {},
202+
dev: {
203+
options: {
204+
keepalive: true
205+
}
206+
}
207+
},
208+
"start-selenium-server": {
209+
dev: {
210+
options: {
211+
downloadUrl: "https://selenium-release.storage.googleapis.com/2.40/" +
212+
"selenium-server-standalone-2.40.0.jar",
213+
downloadLocation: "external/selenium",
214+
serverOptions: {
215+
"Dwebdriver.chrome.driver=node_modules/chromedriver/bin/chromedriver": ""
216+
},
217+
systemProperties: {}
218+
}
219+
}
112220
}
113221
});
114-
222+
grunt.loadNpmTasks( "perfjankie" );
115223
grunt.registerTask( "update-authors", function() {
116224
var getAuthors = require( "grunt-git-authors" ),
117225
done = this.async();
@@ -131,5 +239,5 @@ grunt.registerTask( "update-authors", function() {
131239

132240
grunt.registerTask( "default", [ "jshint", "jscs" ] );
133241
grunt.registerTask( "build", [ "sass", "autoprefixer" ] );
134-
242+
grunt.registerTask( "perf", [ "start-selenium-server", "connect:perf", "perfjankie" ] );
135243
};

package.json

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,22 @@
4343
"dependencies": {},
4444
"devDependencies": {
4545
"commitplease": "2.0.0",
46-
"grunt": "^0.4.5",
46+
"chromedriver": "2.13.0",
47+
"commitplease": "2.0.0",
48+
"ejs-template": "0.1.0",
49+
"grunt": "0.4.5",
4750
"grunt-autoprefixer": "^2.1.0",
48-
"grunt-contrib-jshint": "0.10.0",
51+
"grunt-contrib-jshint": "0.10.0",
52+
"grunt-contrib-connect": "0.9.0",
4953
"grunt-contrib-watch": "^0.6.1",
5054
"grunt-git-authors": "2.0.0",
5155
"grunt-jscs": "0.6.2",
56+
"grunt-sass": "^0.17.0",
57+
"grunt-selenium-server": "0.1.2",
5258
"grunt-svgmin": "^2.0.0",
5359
"grunt-svgstore": "^0.5.0",
54-
"grunt-sass": "^0.17.0"
55-
},
56-
"keywords": []
60+
"grunt-html": "1.6.0",
61+
"perfjankie": "1.1.1"
62+
},
63+
"keywords": []
5764
}

performance/component.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title><%= title %></title>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<%
8+
var stylesheets = "";
9+
css.forEach(function( value ){
10+
stylesheets += "<link rel='stylesheet' href='" + value + "'>";
11+
});
12+
%>
13+
<%- stylesheets %>
14+
</head>
15+
<body>
16+
<h1><%= title %></h1>
17+
<h2>Component Count: <%= count %></h2>
18+
<%- html %>
19+
</body>
20+
</html>

performance/component.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
var components = {
2+
generate: function( frameworkName, component, count ) {
3+
var currentCount = 0,
4+
framework = require( "./frameworks/" + frameworkName + ".js" ),
5+
keys = Object.keys( framework[ component ].variations ),
6+
current = {},
7+
html = "";
8+
9+
function render( i ) {
10+
framework[ component ].variations[ keys[ i ] ].forEach(function( value ) {
11+
current[ keys[ i ] ] = value;
12+
if ( i < keys.length - 1 ) {
13+
render( i + 1 );
14+
} else {
15+
if ( currentCount < count ) {
16+
currentCount++;
17+
html = html + framework[ component ].generator.call( this, current );
18+
}
19+
}
20+
});
21+
}
22+
while ( currentCount < count ) {
23+
render( 0 );
24+
}
25+
return {
26+
html: html,
27+
count: currentCount,
28+
css: framework.css,
29+
title: frameworkName + ": " + component
30+
};
31+
}
32+
};
33+
module.exports = components;

performance/frameworks/bootstrap.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module.exports = {
2+
css: [ "//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" ],
3+
button: {
4+
generator: function( options ) {
5+
var button = "<button class='btn " + options.state + " " + options.size + "' >";
6+
if ( options.icon ) {
7+
button = button + "<span class='glyphicon glyphicon-" + options.icon +
8+
"'></span>";
9+
}
10+
return button + " Button </button>";
11+
},
12+
variations: {
13+
state: [
14+
"btn-default",
15+
"btn-primary",
16+
"btn-success",
17+
"btn-info",
18+
"btn-warning",
19+
"btn-danger",
20+
"btn-link"
21+
],
22+
size: [
23+
"",
24+
"btn-lg",
25+
"btn-sm",
26+
"btn-xs"
27+
],
28+
icon: [
29+
false,
30+
"astrisk",
31+
"plus",
32+
"minus",
33+
"euro",
34+
"fire"
35+
]
36+
}
37+
}
38+
};

performance/frameworks/foundation.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
module.exports = {
2+
css: [
3+
"//cdn.foundation5.zurb.com/foundation.css",
4+
"//cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.eot",
5+
"https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.min.css"
6+
],
7+
button: {
8+
generator: function( options ) {
9+
var button = "<button class='button" + options.state + options.size + options.shape +
10+
"' >";
11+
if ( options.icon ) {
12+
button = button + "<i class='fi-" + options.icon +
13+
"'></i>";
14+
}
15+
return button + " Button </button>";
16+
},
17+
variations: {
18+
state: [
19+
"",
20+
" secondary",
21+
" alert",
22+
" info",
23+
" disabled",
24+
" success"
25+
],
26+
size: [
27+
"",
28+
" tiny",
29+
" small",
30+
" large"
31+
],
32+
shape: [
33+
" round",
34+
" radius",
35+
" expand"
36+
],
37+
icon: [
38+
false,
39+
"compas",
40+
"power",
41+
"crown",
42+
"skull",
43+
"map"
44+
]
45+
}
46+
}
47+
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module.exports = {
2+
css: [ "//code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" ],
3+
button: {
4+
generator: function( options ) {
5+
var position = ( options.icon === "" ) ? "" : options.iconPosition;
6+
return "<button class='ui-btn" +
7+
options.options +
8+
options.theme +
9+
position +
10+
options.icon +
11+
"'>Button</button>";
12+
},
13+
variations: {
14+
theme: [
15+
" ui-btn-a",
16+
" ui-btn-b",
17+
" ui-state-disabled ui-btn-a",
18+
" ui-state-disabled ui-btn-b"
19+
],
20+
options: [
21+
" ui-btn-inline ui-mini",
22+
" ui-btn-inline ui-corner-all",
23+
" ui-btn-inline ui-shadow",
24+
" ui-btn-inline",
25+
" ui-corner-all ui-shadow",
26+
" ui-corner-all ui-shadow ui-btn-inline",
27+
" ui-corner-all ui-shadow ui-mini ui-btn-inline"
28+
],
29+
iconPosition: [
30+
" ui-btn-icon-left",
31+
" ui-btn-icon-top",
32+
" ui-btn-icon-bottom",
33+
" ui-btn-icon-right"
34+
],
35+
icon: [
36+
"",
37+
" ui-icon ui-icon-bars",
38+
" ui-icon ui-icon-bullets",
39+
" ui-icon ui-icon-camera",
40+
" ui-icon ui-icon-audio",
41+
" ui-icon ui-icon-cloud"
42+
]
43+
}
44+
}
45+
};

0 commit comments

Comments
 (0)