diff --git a/bower.json b/bower.json index 4763c82e..c8aecfcc 100644 --- a/bower.json +++ b/bower.json @@ -37,7 +37,9 @@ "font-lato-2-subset": "~0.3.5", "packery": "~1.2.3", "draggabilly": "~1.1.0", - "angular-elastic": "~2.3.3" + "angular-elastic": "~2.3.3", + "quick-ng-repeat": "~0.0.1", + "angular-vs-repeat": "~1.0.0-rc2" }, "private": true, "resolutions": { diff --git a/res/app/app.js b/res/app/app.js index ec9d0a66..7e9cb754 100644 --- a/res/app/app.js +++ b/res/app/app.js @@ -17,7 +17,8 @@ angular.module('app', [ require('./menu').name, require('./settings').name, require('./help').name, - require('./../common/lang').name + require('./../common/lang').name, + require('./../test/samples/vs-repeat').name ]) .config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) { diff --git a/res/test/samples/vs-repeat/app-controller.js b/res/test/samples/vs-repeat/app-controller.js new file mode 100644 index 00000000..00803a6c --- /dev/null +++ b/res/test/samples/vs-repeat/app-controller.js @@ -0,0 +1,53 @@ +module.exports = function ($scope, $location) { + + function getRegularArray(size) { + var res = []; + for (var i = 0; i < size; i++) { + res.push({text: i}); + } + return res; + } + + $scope.items = { + collection: getRegularArray(1000) + }; + $scope.$root.arraySize = 1000; + $scope.switchCollection = function () { + var parsed = parseInt($scope.newArray.size, 10); + if (!isNaN(parsed)) { + $scope.$root.arraySize = parsed; + $scope.items = { + collection: getRegularArray(parsed) + }; + } + }; + $scope.getDomElementsDesc = function () { + var arr = []; + var elems = document.querySelectorAll('.item-element.well'); + elems = Array.prototype.slice.call(elems); + elems.forEach(function (item) { + arr.push(item.innerHTML.trim()); + }); + return arr; + } + $scope.newArray = {}; + $scope.inputKeyDown = function (e) { + if (e.keyCode == 13) { + $scope.switchCollection(); + } + }; + + $scope.outerArray = getRegularArray(2); + $scope.thirdArray = getRegularArray(30); + + $scope.$watch(function () { + return $location.search(); + }, function (obj) { + if (obj.tab) + $scope.tab = obj.tab + ''; + }, true); + + $scope.$watch('tab', function (tab) { + $location.search({tab: tab}); + }); +} diff --git a/res/test/samples/vs-repeat/index.js b/res/test/samples/vs-repeat/index.js new file mode 100644 index 00000000..6f9ce521 --- /dev/null +++ b/res/test/samples/vs-repeat/index.js @@ -0,0 +1,14 @@ +require('./vs-repeat.less') + +require('angular-vs-repeat') + +module.exports = angular.module('stf.vs-repeat', [ + 'vs-repeat' +]) + .controller('PerfVsRepeatCtrl', require('./vs-repeat-controller')) + .controller('AppVsRepeatCtrl', require('./app-controller')) + .config(['$routeProvider', function ($routeProvider) { + $routeProvider.when('/test/samples/vs-repeat', { + template: require('./vs-repeat.html') + }) + }]) diff --git a/res/test/samples/vs-repeat/vs-repeat-controller.js b/res/test/samples/vs-repeat/vs-repeat-controller.js new file mode 100644 index 00000000..cd246ea7 --- /dev/null +++ b/res/test/samples/vs-repeat/vs-repeat-controller.js @@ -0,0 +1,26 @@ +module.exports = function ($scope) { + function getArray(size) { + var arr = []; + for (var i = 0; i < size; i++) { + arr.push({ + a: '', + b: '' + }) + } + return arr; + } + + $scope.$watch('arraySize', function (s) { + $scope.bar = getArray(+s); + }); + + var interval = setInterval(function interval() { + var t1 = Date.now(); + $scope.$digest(); + $scope.digestDuration = (Date.now() - t1); + }, 1000); + + $scope.$on('$destroy', function () { + clearInterval(interval); + }); +} diff --git a/res/test/samples/vs-repeat/vs-repeat.html b/res/test/samples/vs-repeat/vs-repeat.html new file mode 100644 index 00000000..e0bbbbfd --- /dev/null +++ b/res/test/samples/vs-repeat/vs-repeat.html @@ -0,0 +1,160 @@ + +
+ The following example shows the performance benefits of using angular-vs-repeat +
++ If you don't look under the hood both lists look exactly the same. On the left size the vs-repeat directive + was used, whereas on the right side there is a plain regular ng-repeat. Above each of those lists the $digest cycle duration + gauge is placed (updates every second) so you can see how many milliseconds it takes to run a $digest with and without vs-repeat. +
++ Try with a 10 000 elements array size (using the form below, and be careful, note that the UI will stall for a significant amout of time). + You can see that the $digest duration with vs-repeat stays on the same level (it actually depends on the container size), while the $digest duration on the right side (without vs-repeat) increases dramatically. Also note that each of those repeated elements consist of just two inputs and a binding, but if there were more complex elements inside, with other directives, watchers etc. the array size threshold for experiencing a 'laggy' UI would be much smaller. +
+
+
+
+ {{el}}
+
+
+
+