Skip to content

Commit 3944134

Browse files
committed
Initial commit
1 parent 32952fd commit 3944134

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2984
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,10 @@ build/Release
2525
# Dependency directory
2626
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
2727
node_modules
28+
29+
.idea
30+
.DS_Store
31+
*/dist/
32+
angular2/app/app.js
33+
angular2/app/app.js.map
34+
tests/results/completed/

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,45 @@
11
# js-framework-benchmark
2+
3+
This is a simple benchmark for several javascript frameworks. The benchmarks creates a large table with randomized entries and measures the time for various operations.
4+
5+
This work is derived from a benchmark that Richard Ayotte published on https://gist.github.com/RichAyotte/a7b8780341d5e75beca7 and adds more framework and more operations.
6+
7+
It's also uses the work of ShMcK Framework-Performance-Tests-with-Meteor who put Protractor and BenchPress wonderfully to work.
8+
9+
Thanks to both for their great work.
10+
11+
## Prerequsites
12+
13+
Have node.js installed. If you want to do yourself a favour use nvm for that. The benchmark has been tested with node 5.1+.
14+
15+
## Building
16+
17+
`npm install`
18+
`npm run build`
19+
The latter calls npm build-prod in each subproject.
20+
21+
## Running in the browser
22+
23+
Execute `npm start` to start a http-server for the web pages.
24+
Open [http://localhost:8080](http://localhost:8080/) and choose the directory for the framework you want to test
25+
26+
## Execute the benchmarks with protractor and benchpress
27+
28+
`npm start`
29+
30+
`cd tests`
31+
`npm run webdriver-manager`
32+
open a new shell in the tests directory
33+
`npm run protractor`
34+
35+
Open [http://localhost:8080/tests/chart.html](http://localhost:8080/tests/chart.html) for the results
36+
37+
## About the benchmarks
38+
39+
* page load & create 1000 rows: Time for page load and creating 1000 rows.
40+
* create 1000 rows: Measures the time for creating 1000 rows, but after the page was loaded.
41+
* update 1000 rows: Time to replace all 1000 rows with new rows. It performs a few invocations as a warmup and measures the the time to replace the rows.
42+
* 10 x add 10 rows: Time for adding a few items. It measures the time to add 10 times 10 rows.
43+
* partial update: Time for a partial update. Appends a dot to the text of every 10th row and keeps the other rows unchanged.
44+
* select 10 rows: Measures the time to click the first ten rows one after the other. Each row is highlighted when clicked.
45+
* remove 10 rows: Measures the time to remove the first ten rows one after the other.

angular/css/main.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
body {
2+
padding: 0;
3+
margin: 0;
4+
overflow-y: scroll;
5+
}
6+
#duration {
7+
padding-top: 0px;
8+
}
9+
.jumbotron {
10+
padding-top:10px;
11+
padding-bottom:10px;
12+
}
13+
.test-data a {
14+
display: block;
15+
}

angular/index.html

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Angular</title>
6+
<script src='node_modules/jquery/dist/jquery.min.js'></script>
7+
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
8+
<link href="css/main.css" rel="stylesheet"/>
9+
<script src='dist/main.js'></script>
10+
</head>
11+
<body ng-app="app">
12+
<div class="container" ng-controller="HomeController as homeController">
13+
<div class="jumbotron">
14+
<div class="row">
15+
<div class="col-md-8">
16+
<h1>Angular</h1>
17+
</div>
18+
<div class="col-md-4">
19+
<button type="button" class="btn btn-primary btn-block" id="add" ng-click="homeController.add()">Add 10 rows</button>
20+
<button type="button" class="btn btn-primary btn-block" id="run" ng-click="homeController.run()">Create 1000 rows</button>
21+
<button type="button" class="btn btn-primary btn-block" id="update" ng-click="homeController.update()">Update every 10th row</button>
22+
<h3 id="duration"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span>&nbsp;</h3>
23+
</div>
24+
</div>
25+
</div>
26+
<table class="table table-hover table-striped test-data">
27+
<tr ng-repeat="item in homeController.data track by item.id" ng-class="{ danger: item.id === homeController.selected }">
28+
<td class="col-md-1">{{item.id}}</td>
29+
<td class="col-md-4">
30+
<a ng-click="homeController.select(item)">{{item.label}}</a>
31+
</td>
32+
<td class="col-md-1"><a ng-click="homeController.del(item)"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a></td>
33+
<td class="col-md-6"></td>
34+
</tr>
35+
</table>
36+
</div>
37+
</body>
38+
</html>

angular/package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "js-framework-benchmark-angular",
3+
"version": "1.0.0",
4+
"description": "Boilerplate for Angular.js",
5+
"scripts": {
6+
"build-dev": "webpack -w -d -c webpack.config.js",
7+
"build-prod": "webpack -p -c webpack.config.js",
8+
"start": "http-server -c-1 ."
9+
},
10+
"keywords": [
11+
"angular"
12+
],
13+
"author": "Stefan Krause",
14+
"license": "Apache-2.0",
15+
"homepage": "https://github.com/krausest/js-framework-benchmark",
16+
"repository" :
17+
{ "type" : "git",
18+
"url" : "https://github.com/krausest/js-framework-benchmark.git"
19+
},
20+
"devDependencies": {
21+
"babel-core": "^4.7.4",
22+
"babel-loader": "^4.1.0",
23+
"http-server": "^0.8.5",
24+
"webpack": "^1.7.2"
25+
},
26+
"dependencies": {
27+
"angular": "^1.4.3",
28+
"bootstrap": "^3.3.6",
29+
"jquery": "*"
30+
}
31+
}

angular/src/HomeController.es6.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
export default class HomeController {
2+
constructor($scope) {
3+
console.log("$scope",$scope);
4+
this.$scope = $scope;
5+
this.start = 0;
6+
this.data = [];
7+
this.id = 1;
8+
}
9+
10+
buildData(count = 1000) {
11+
var adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"];
12+
var colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"];
13+
var nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"];
14+
var data = [];
15+
for (var i = 0; i < count; i++) {
16+
data.push({ id: this.id++, label: adjectives[this._random(adjectives.length)] + " " + colours[this._random(colours.length)] + " " + nouns[this._random(nouns.length)] });
17+
}
18+
return data;
19+
}
20+
printDuration() {
21+
this.$scope.$$postDigest(function() {
22+
let duration = Math.round(performance.now()-this.start);
23+
document.getElementById("duration").innerHTML = duration + " ms";
24+
}.bind(this));
25+
}
26+
_random(max) {
27+
return Math.round(Math.random() * 1000) % max;
28+
}
29+
add() {
30+
this.start = performance.now();
31+
this.data = this.data.concat(this.buildData(10));
32+
this.printDuration();
33+
}
34+
select(item) {
35+
this.start = performance.now();
36+
this.selected = item.id;
37+
this.printDuration();
38+
}
39+
del(item) {
40+
this.start = performance.now();
41+
const idx = this.data.findIndex(d => d.id===item.id);
42+
this.data.splice(idx, 1);
43+
this.printDuration();
44+
}
45+
update() {
46+
this.start = performance.now();
47+
for (let i=0;i<this.data.length;i+=10) {
48+
this.data[i].label += '.';
49+
}
50+
this.printDuration();
51+
}
52+
run() {
53+
this.start = performance.now();
54+
this.data = this.buildData();
55+
this.printDuration();
56+
};
57+
}
58+
59+
HomeController.$inject = ['$scope'];

angular/src/angularmin.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require('./../node_modules/angular/angular.min');
2+
module.exports = angular;

angular/src/main.es6.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
require('babel-core/lib/babel/polyfill');
4+
5+
const angular = require('./angularmin');
6+
const HomeController = require('HomeController');
7+
8+
console.log("angular", angular);
9+
10+
angular.module('app', [])
11+
.controller('HomeController',HomeController);

angular/webpack.config.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
3+
var cache = {};
4+
var loaders = [
5+
{
6+
test: /\.es6\.js$/,
7+
loader: 'babel-loader'
8+
},
9+
{
10+
test: /\.css$/,
11+
loader: 'style-loader!css-loader'
12+
}
13+
];
14+
var extensions = [
15+
'', '.js', '.es6.js'
16+
];
17+
18+
module.exports = [{
19+
cache: cache,
20+
module: {
21+
loaders: loaders
22+
},
23+
entry: {
24+
main: './src/main',
25+
},
26+
output: {
27+
path: './dist',
28+
filename: 'main.js'
29+
},
30+
resolve: {
31+
extensions: extensions,
32+
root: [
33+
__dirname,
34+
__dirname + '/src'
35+
],
36+
alias: {
37+
}
38+
}
39+
}];

angular2/app/app.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import {bootstrap} from 'angular2/platform/browser'
2+
import {Component, View} from 'angular2/core';
3+
4+
@Component({
5+
selector: 'my-app'
6+
})
7+
@View({
8+
templateUrl: 'template.html'
9+
})
10+
class MyAppComponent {
11+
data: Array<any> = [];
12+
selected: string = undefined;
13+
start: number = 0;
14+
id: number = 1;
15+
16+
constructor() {
17+
}
18+
buildData(count: number = 1000): Array<string> {
19+
var adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"];
20+
var colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"];
21+
var nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"];
22+
var data = [];
23+
for (var i = 0; i < count; i++) {
24+
data.push({id: this.id, label: adjectives[this._random(adjectives.length)] + " " + colours[this._random(colours.length)] + " " + nouns[this._random(nouns.length)] });
25+
this.id++;
26+
}
27+
return data;
28+
}
29+
30+
printDuration() {
31+
setTimeout(() => {
32+
let duration = Math.round(performance.now()-this.start);
33+
document.getElementById("duration").innerHTML = duration + " ms";
34+
});
35+
}
36+
37+
_random(max: number) {
38+
return Math.round(Math.random()*1000)%max;
39+
}
40+
41+
select(item, event) {
42+
this.start = performance.now();
43+
event.preventDefault();
44+
this.selected = item.id;
45+
this.printDuration();
46+
}
47+
48+
delete(item, event) {
49+
this.start = performance.now();
50+
event.preventDefault();
51+
const idx = this.data.findIndex(d => d.id===item.id);
52+
this.data.splice(idx, 1);
53+
this.printDuration();
54+
}
55+
56+
run(event) {
57+
this.start = performance.now();
58+
this.data = this.buildData();
59+
this.printDuration();
60+
}
61+
62+
add(event) {
63+
this.start = performance.now();
64+
this.data = this.data.concat(this.buildData(10));
65+
this.printDuration();
66+
}
67+
68+
update(event) {
69+
this.start = performance.now();
70+
for (let i=0;i<this.data.length;i+=10) {
71+
this.data[i].label += '.';
72+
}
73+
this.printDuration();
74+
}
75+
76+
}
77+
78+
bootstrap(MyAppComponent);

0 commit comments

Comments
 (0)