Angular

The recent MVC landscape with Angular+React and Backbone+React

Sun Jun 8, 2014

This post might bring in some arguments for both parties that favour one of the framework then the other, but this will be a worth while comparision to take a look at the recent MVC landscape. Just to clarify - I'm still relatively new to Angular.

Lets be clear - React is a component that is designed and focused to replace the 'V' component under a MVC framework. The most recognise MVC frameworks are Backbone & Angular, and it's starting to increasingly standout that React is able to replace the 'V' component due to its virtual dom design, minimal exposure of real dom elements and data-binding handling. It is also proven from this post that Angular + React provides the fastest rendering.

To achieve fast render and low inital load speed, the design of the component hierarchy structure is relatively important. In Angular, React needs to be initiated at the controller. For Backbone, on the other hand needs to be initiated at the router.

Link to Angular+React Demo
Link to Backbone+React Demo

//Angular Example
angular.module('fasterAngular', []).
controller('mycontroller', ['$scope', function($scope){
   $scope.framework = 'ReactJs';
   $scope.data = [];
   // Fill the data map with random data
   $scope.refresh = function(){
       for(var i = 0; i < 1500; ++i) {
           $scope.data[i] = {};
           for(var j = 0; j < 5; ++j) {
               $scope.data[i][j] = Math.random();
           }
       }
   }

   $scope.refresh();

   $scope.$watchCollection('data', function(newValue, oldValue){
       React.renderComponent(
           MYLIST({data:newValue}),
           document.getElementById("fastRepeatArea")
       );
   })
}])

//Backbone example
$(document).ready(function () {
  new (Backbone.Router.extend({
    initialize : function () {
        var data = [];
        var refresh = function () {
          for(var i = 0; i < 1500; ++i) {
                  data[i] = {};
                  for(var j = 0; j < 5; ++j) {
                      data[i][j] = Math.random();
                  }
              }
          React.renderComponent(
            MYLIST({data:data}),
            document.getElementById("fastRepeatArea")
          );
        };
        refresh();
        $('button#refreshBtn').click(function () {
          refresh();
        });
    },
  }))();
});

React is initiated under the same flow and it would achieve the same render speed. This example can be further improved by delegating the data change event and click event to React or using mixins to listen to partial changes. Instead of having it through the Angular controller or Backbone router.

At this point, Angular+React and Backbone+React would be equivalent. Now lets take a look at the required components and initial loading speed.

According to Mithril, Angular takes 7.49ms to load and Backbone takes 18.54ms to load. Another important to note is Backbone is light weight but it still depends upon underscore & jquery. Those add up during initial script request!

I believe this pretty much dictates which combination is the go to framework for heavy web apps. Every second counts to keep your user on your site!

The contender in the market called Facebook React, I'll just call it React for short. React is a 'View' Framework. So in terms of a MVC, its the 'V' Component. Suprisingly React further simplified the entire landscape of 'View' framework. It only expose the real nodes that you have

Lets see how this will look like in React, ive also included the propeller react.backbone. It allows us to feed in backbone models into react and databind with mixin.


<!– html structure –>
<html>
  <body>
  </body>
</html>

//javascript code
/** @jsx React.DOM **/
‘use strict’;

define ([
  'jquery', backbone', 'react', 'react.backbone'
], function (
  $, Backbone, React,
) {

  var CommentComponent = React.createBackboneClass({
    var comments = this.props.collection.map(function(item) {
      return (
        {item.get('comment')}
      )
    });
    return (
      <div>
        {comments}
      </div>
    );
  });

  var StatsComponent = React.createBackboneClass({
    render : function () {
      return (
        <div>
          {/* html template */}
        </div>
      );
    }
  });

  var MenuComponent = React.createBackboneClass({
    render : function () {
      return (
        <div>
          {/* html template */}
        </div>
      );
    }
  });

  var WidgetLayout = React.createBackboneClass({
    componentWillMount : function () {
      this.collection = Backbone.Collection();
    },
    render : function () {
      return (
        <StatsComponent />
        <CommentsComponent collection={this.collection}/>
      )
    };
  });

  var AppLayout = React.createBackboneClass({
    render : function () {
      return (
        <div>
            <MenuComponent />
            <WidgetLayout />
        </div>
      );
    };
  });
  React.renderComponent({
    <AppLayout />,
    $('body')[0]
  });
});

The code base is smaller, easier to understand and to control. Now some may ask about Angular + React comparing with Backbone + React. For this I’ll leave it to next post, but this is now pretty clear Marionette is out of the game.

Goodbye Marionette & Hello React

Wed May 28, 2014

I have been developing a lot of large javascript web apps that requires a lot of subview management or componets and decentralize the model dependecies to better suit the component re-usability. It was not till early this year, I was still designing them with Backbone + Marionette. Now it's Backbone + React or Angular + React. For this post let's concentrate in comparing Backbone + Mariontte & Backbone + React. As we all know, Backbone 'View' itself is a design flaw. It had a lot of issues regarding its memory management and sub view management. Marionette on the other hand, did help solved the sub view management and memory issues by offering a wide range of common designs and design patterns to help build the application.

Although Marionette provided a decent way to handle layout, subviews and code management, it is still too dependent on Backbone and gets more complex upon further sub view nesting. In Marionette the view is represented as a tree, the subviews is also part of the tree, thus if to render the middle layer must destruct and a rebuilt must occur. As well as rendering multiple Marionette Layers and Regions, although these Marionette functionalites are really awesome which helped took out the pain in backbone. While nesting those components doesnt play nicely with each other and hard to decouple, causing the sub layouts and sub regions to have an event show fire before its parent fires the show event.

Consider in Marionette, you used a layout to display a widget on a page. Within the widget there is also a layout before it calls the itemview. In other words nested layout then itemview.

    
      
      <html>
        <body>
          
          
</body> </html>
//javascript code 'use strict'; define([ 'backbone', 'marionette' ], function( Backbone, Marionette ) { var AppLayout = Backbone.Marionette.Layout.extend({ template : '#some-layout-template' regions : { widget : '#widget', menu : '#menu' } }); var MenuItem = Backbone.Marionette.IteView.extend({ template : '#some-template' }); var CommentItem = Backbone.Marionette.ItemView.extend({ template : '#some-comment-template' }); var StatsItem = Backbone.Marionette.ItemView.extend({ template : '#some-template' }); var CommentsCompositeView = Backbone.CompositeView.extend({ template : '#some-comment-template', itemView : CommentItem }); var WidgetLayout = Backbone.Marionette.Layout.extend({ initialize : function () { this.collection = new Backbone.Collection(); }, template : '#widget-layout-template', regions : { stats : new Marionette.Region({ el : "#stats-region" }) comments : new Marionette.Region({ el : '#comment-region' }) }, onShow : function () { this.regions.stats.show(new StatsItem( model : someModel )); this.regions.comments.show(new CommentsCompositeView({ collection : this.collection })); } }); var layout = new AppLayout(); layout.render(); layout.widget.show(new WidgetLayout()); layout.menu.show(new MenuItem()); });

In this example we will run into a render issue with the sub region fire before the parent does.

Now came 2014 and there is a new contender in the market called Facebook React, I'll just call it React for short. React is a 'View' Framework. So in terms of a MVC, its the 'V' Component. Suprisingly React further simplified the entire landscape of 'View' framework. It only expose the real nodes that you have

Lets see how this will look like in React, ive also included the propeller react.backbone. It allows us to feed in backbone models into react and databind with mixin.

  
      <!– html structure –>
      <html>
        <body>
        </body>
      </html>
  
  
    //javascript code
    /** @jsx React.DOM **/
    ‘use strict’;

define ([
  'jquery', backbone', 'react', 'react.backbone'
], function (
  $, Backbone, React,
) {

  var CommentComponent = React.createBackboneClass({
    var comments = this.props.collection.map(function(item) {
      return (
        {item.get('comment')}
      )
    });
    return (
      <div>
        {comments}
      </div>
    );
  });

  var StatsComponent = React.createBackboneClass({
    render : function () {
      return (
        <div>
          {/* html template */}
        </div>
      );
    }
  });

  var MenuComponent = React.createBackboneClass({
    render : function () {
      return (
        <div>
          {/* html template */}
        </div>
      );
    }
  });

  var WidgetLayout = React.createBackboneClass({
    componentWillMount : function () {
      this.collection = Backbone.Collection();
    },
    render : function () {
      return (
        <StatsComponent />
        <CommentsComponent collection={this.collection}/>
      )
    };
  });

  var AppLayout = React.createBackboneClass({
    render : function () {
      return (
        <div>
            <MenuComponent />
            <WidgetLayout />
        </div>
      );
    };
  });
  React.renderComponent({
    <AppLayout />,
    $('body')[0]
  });
});

The code base is smaller, easier to understand and to control. Now some may ask about Angular + React comparing with Backbone + React. For this I’ll leave it to next post, but this is now pretty clear Marionette is out of the game.