Angular VS Knockout VS Ember VS React VS Matreshka (1000) (v589)

Revision 589 of this benchmark created by Andrey on


Description

This is a simple rendering speed test between the most popular libraries/frameworks.

Preparation HTML

<!-- Jquery -->
<script src="https://cdn.jsdelivr.net/jquery/2.1.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/angularjs/1.3.14/angular.min.js"></script>
<script src="https://cdn.jsdelivr.net/knockout/3.3.0/knockout.js"></script>
<script src="https://cdn.jsdelivr.net/handlebarsjs/1.3.0/handlebars.js"></script>
<script src="https://cdn.jsdelivr.net/emberjs/1.5.0/ember.min.js"></script>
<script src="https://cdn.jsdelivr.net/react/0.10.0/react-with-addons.js"></script>
<script src="https://cdn.jsdelivr.net/matreshka/latest/matreshka.min.js"></script>

<script>
        angular.module('test', [])
                .controller('Ctrl', ['$scope', function ($scope) {

                        $scope.data = [];

                        window.ANGdigest = function(){
                                $scope.$digest();
                        };

                        window.ANGclear = function () {
                                $scope.data.splice(0, $scope.data.length);
                        };

                        window.ANGpush = function (data) {
                                $scope.data.push(data + $scope.data.length);
                        };

                }]);
</script>

<!-- Angular -->
<div ng-app="test">
        Angular:
        <span ng-controller="Ctrl" id="angList"><span ng-repeat="item in data">{{item}}</span></span>
</div>


<!-- Knockout -->
<div id="koapp">
        Knockout:
        <span data-bind="foreach: data"><span data-bind="text: $data"></span></span>
</div>

<!-- Ember -->

<div id="emapp"></div>
<script type="text/x-handlebars">
        Ember:
  <span>
    {{#each EMapp.data}}<span>{{this}}</span>{{/each}}
  </span>
</script>


<!-- React -->
<div id="react">
        React: <span id="reactMountNode"></span>
</div>


<!-- Matreshka -->
<div id="matreshka">
        Matreshka: <span id="matreshkaMountNode"></span>
</div>


<script>
        $(function () {
                window.KOData = ko.observableArray();
                var KOviewmodel = {data: KOData};

                var ENV = {EXTEND_PROTOTYPES: false};

                var ReactComponent = React.createClass({
                        displayName: 'PerfTest',
                        getInitialState: function () {
                                return {data: []};
                        },
                        render: function () {
                                var res = [];
                                for (var i = 0; i < this.state.data.length; i++) {
                                        res.push(React.DOM.span({key: 'test' + i}, this.state.data[i]));
                                }
                                return React.DOM.span(null, res);
                        }
                });


                var MatreshkaModel = MK.Class({
                        'extends': MK.Object,
                        constructor: function () {
                                this.on('render', function (evt) {
                                        this.bindNode('value', ':sandbox', {
                                                setValue: function (v) {
                                                        this.innerHTML = v;
                                                }
                                        });
                                });
                        }
                });

                var matreshkaApp = new MK.Class({
                        'extends': MK.Array,
                        Model: MatreshkaModel,
                        itemRenderer: '<span>',
                        constructor: function () {
                                this.bindNode('sandbox', '#matreshkaMountNode');
                        }
                });


                ko.applyBindings(KOviewmodel, document.getElementById('koapp'));
                window.KOclear = function () {
                        KOData.splice(0, KOData().length);
                };
                window.KOpush = function (data) {
                        KOData.push(data);
                };


                EMapp = Ember.Application.create({
                        rootElement: '#emapp'
                });
                EMapp.data = Ember.A();

                window.EMclear = function () {
                        EMapp.data.clear();
                };
                window.EMpush = function (data) {
                        EMapp.data.pushObject(data);
                };


                window.reactComp = ReactComponent();
                React.renderComponent(reactComp, $('#reactMountNode')[0]);

                window.RClear = function () {
                        reactComp.setState({data: []})
                };

                window.RPush = function (data) {
                        window.RstateData = reactComp.state.data;
                        RstateData.push(data);
                };
                
                window.RInit = function(){
                        reactComp.setState({data: RstateData});
                };


                window.MKpush = function (value) {
                        matreshkaApp.push({value: value});
                };

                window.MKclear = function () {
                        matreshkaApp.recreate();
                };
        });
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Angular 1000
        ANGclear();
        for (var i = 0; i < 1000; i++)
                ANGpush("ngitem");
        ANGdigest();
 
ready
React 1000
        RClear();
        for (var i = 0; i < 1000; i++)
                RPush("ritem");
        RInit()
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.