Add todoapp benchmark

This commit is contained in:
Roman Vishnevskii 2017-04-24 16:00:32 +07:00
commit 02e7b40c07
218 changed files with 63168 additions and 0 deletions

View file

@ -0,0 +1 @@
(function(){"use strict";angular.module("todoCtrl",[]).controller("TodoCtrl",function TodoCtrl($scope,$location){var TC=this;var todos=TC.todos=[];TC.ESCAPE_KEY=27;TC.editedTodo={};function resetTodo(){TC.newTodo={title:"",completed:false}}resetTodo();if($location.path()===""){$location.path("/")}TC.location=$location;$scope.$watch("TC.location.path()",function(path){TC.statusFilter={"/active":{completed:false},"/completed":{completed:true}}[path]});$scope.$watch("TC.todos",function(){TC.remainingCount=todos.filter(function(todo){return!todo.completed}).length;TC.allChecked=TC.remainingCount===0},true);TC.addTodo=function(){var newTitle=TC.newTodo.title=TC.newTodo.title.trim();if(newTitle.length===0){return}todos.push(TC.newTodo);resetTodo()};TC.editTodo=function(todo){TC.editedTodo=todo;TC.originalTodo=angular.copy(todo)};TC.doneEditing=function(todo,index){TC.editedTodo={};todo.title=todo.title.trim();if(!todo.title){TC.removeTodo(index)}};TC.revertEditing=function(index){TC.editedTodo={};todos[index]=TC.originalTodo};TC.removeTodo=function(index){todos.splice(index,1)};TC.clearCompletedTodos=function(){TC.todos=todos=todos.filter(function(val){return!val.completed})};TC.markAll=function(completed){todos.forEach(function(todo){todo.completed=completed})}});angular.module("todoFocus",[]).directive("todoFocus",function($timeout){return function(scope,elem,attrs){scope.$watch(attrs.todoFocus,function(newVal){if(newVal){$timeout(function(){elem[0].focus()},0,false)}})}});angular.module("todomvc",["todoCtrl","todoFocus"])})();

View file

@ -0,0 +1,77 @@
<!doctype html>
<html lang="en" ng-app="todomvc" data-framework="angularjs">
<head>
<meta charset="utf-8">
<title>AngularJS • TodoMVC</title>
<link rel="stylesheet" href="node_modules/todomvc-common/base.css">
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
<style>
[ng-cloak] {
display: none;
}
</style>
</head>
<body>
<section class="todoapp" ng-controller="TodoCtrl as TC">
<header class="header">
<h1>todos</h1>
<form id="todo-form">
<input class="new-todo" placeholder="What needs to be done?" ng-model="TC.newTodo.title" autofocus ng-keydown="($event.keyCode === 13) && TC.addTodo()">
</form>
</header>
<section class="main" ng-show="TC.todos.length" ng-cloak>
<input class="toggle-all" type="checkbox" ng-model="TC.allChecked" ng-click="TC.markAll(TC.allChecked)">
<label for="toggle-all">Mark all as complete</label>
<ul class="todo-list">
<li ng-repeat="todo in TC.todos | filter:TC.statusFilter track by $index" ng-class="{completed: todo.completed, editing: todo === TC.editedTodo}">
<div class="view">
<input class="toggle" type="checkbox" ng-model="todo.completed">
<label ng-dblclick="TC.editTodo(todo)">{{todo.title}}</label>
<button class="destroy" ng-click="TC.removeTodo($index)"></button>
</div>
<form ng-submit="TC.doneEditing(todo, $index)">
<input class="edit" ng-trim="false" ng-model="todo.title" ng-blur="TC.doneEditing(todo, $index)" ng-keydown="($event.keyCode === TC.ESCAPE_KEY) && TC.revertEditing($index)" todo-focus="todo === TC.editedTodo">
</form>
</li>
</ul>
</section>
<footer class="footer" ng-show="TC.todos.length" ng-cloak>
<span class="todo-count"><strong>{{TC.remainingCount}}</strong>
<ng-pluralize count="TC.remainingCount" when="{ one: 'item left', other: 'items left' }"></ng-pluralize>
</span>
<ul class="filters">
<li>
<a ng-class="{selected: TC.location.path() == '/'} " href="#/">All</a>
</li>
<li>
<a ng-class="{selected: TC.location.path() == '/active'}" href="#/active">Active</a>
</li>
<li>
<a ng-class="{selected: TC.location.path() == '/completed'}" href="#/completed">Completed</a>
</li>
</ul>
<button class="clear-completed" ng-click="TC.clearCompletedTodos()" ng-show="TC.remainingCount < TC.todos.length">Clear completed</button>
</footer>
</section>
<footer class="info">
<p>Double-click to edit a todo</p>
<p>Credits:
<a href="http://twitter.com/cburgdorf">Christoph Burgdorf</a>,
<a href="http://ericbidelman.com">Eric Bidelman</a>,
<a href="http://jacobmumm.com">Jacob Mumm</a> and
<a href="http://blog.igorminar.com">Igor Minar</a>
</p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script>
window.requestAnimationFrame = window.webkitRequestAnimationFrame = function(callback) {
callback();
};
</script>
<script src="node_modules/angular/angular.js"></script>
<script src="build.min.js"></script>
</body>
</html>

View file

@ -0,0 +1,113 @@
/* jshint undef: true, unused: true */
/*global angular */
(function () {
'use strict';
angular.module('todoCtrl', [])
/**
* The main controller for the app. The controller:
* - retrieves and persists the model via the todoStorage service
* - exposes the model to the template and provides event handlers
*/
.controller('TodoCtrl', function TodoCtrl($scope, $location) {
var TC = this;
var todos = TC.todos = [];
TC.ESCAPE_KEY = 27;
TC.editedTodo = {};
function resetTodo() {
TC.newTodo = {title: '', completed: false};
}
resetTodo();
if ($location.path() === '') {
$location.path('/');
}
TC.location = $location;
$scope.$watch('TC.location.path()', function (path) {
TC.statusFilter = { '/active': {completed: false}, '/completed': {completed: true} }[path];
});
// 3rd argument `true` for deep object watching
$scope.$watch('TC.todos', function () {
TC.remainingCount = todos.filter(function (todo) { return !todo.completed; }).length;
TC.allChecked = (TC.remainingCount === 0);
}, true);
TC.addTodo = function () {
var newTitle = TC.newTodo.title = TC.newTodo.title.trim();
if (newTitle.length === 0) {
return;
}
todos.push(TC.newTodo);
resetTodo();
};
TC.editTodo = function (todo) {
TC.editedTodo = todo;
// Clone the original todo to restore it on demand.
TC.originalTodo = angular.copy(todo);
};
TC.doneEditing = function (todo, index) {
TC.editedTodo = {};
todo.title = todo.title.trim();
if (!todo.title) {
TC.removeTodo(index);
}
};
TC.revertEditing = function (index) {
TC.editedTodo = {};
todos[index] = TC.originalTodo;
};
TC.removeTodo = function (index) {
todos.splice(index, 1);
};
TC.clearCompletedTodos = function () {
TC.todos = todos = todos.filter(function (val) {
return !val.completed;
});
};
TC.markAll = function (completed) {
todos.forEach(function (todo) {
todo.completed = completed;
});
};
});
angular.module('todoFocus', [])
/**
* Directive that places focus on the element it is applied to when the expression it binds to evaluates to true
*/
.directive('todoFocus', function ($timeout) {
return function (scope, elem, attrs) {
scope.$watch(attrs.todoFocus, function (newVal) {
if (newVal) {
$timeout(function () {
elem[0].focus();
}, 0, false);
}
});
};
});
/**
* The main TodoMVC app module that pulls all dependency modules declared in same named files
*
* @type {angular.Module}
*/
angular.module('todomvc', ['todoCtrl', 'todoFocus']);
})();

View file

@ -0,0 +1,14 @@
{
"private": true,
"scripts": {
"make": "uglifyjs js/app.js -o build.min.js"
},
"dependencies": {
"angular": "^1.5.8",
"todomvc-app-css": "^2.0.6",
"todomvc-common": "^1.0.2"
},
"devDependencies": {
"uglify-js": "^2.6.4"
}
}

View file

@ -0,0 +1,19 @@
# Angular TodoMVC for Benchmarking
This is an update of the
_[Angular TodoMVC example](https://github.com/tastejs/todomvc/tree/gh-pages/examples/angularjs-perf)_
with the following changes:
* Upgrade to Angular 1.5.7
* Update todomvc-app-css to 2.0.6 to match other examples in this benchmark
* Remove localStorage functionality - not relevant to measuring render performance
* Concat JS into one file
* Minify with uglify
This example is listed as "performance optimized" in the TodoMVC repository, but doesn't appear to make any performance improvements to the basic example other than excluding all features not mentioned in the app specification. Therefore, it should count as having no optimizations for the purposes of this benchmark.
# Building
1. `npm install`
2. `npm run make`
3. Open a local server (e.g. with `npm install -g http-server`) and open index.html