Javascript

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.

JavaScript Function Crib Sheet

Wed May 8, 2013

Getting Lazy! So created a javascript function cheat sheet to share with the travellers here. Hope it will be help many of you.

The cryptsheet includes these functions and can be found here : https://github.com/alfredkam/jsFunctions

General Laziness::
- jquery toggle string
- jquery enter keyup event

Mathematical Functions::
- n choose r
- Binomial Distribution
- Probability Mass Function (Useful when wanted to create a bell curve)
- Summation

If the function your missing is not listed, comment below and i may be able to write one.

Searchable Hash Bang (SEO)

Fri Feb 1, 2013

Having a dynamic website, AJAX is often used and rely on hash bang to act as a http GET to let the site be interactive. Inorder to have your application searchable / crawable, there are couple of rules to follow as suggested by the google specs.

Assuming your too lazy to checkout the specs. In summary the hash bang should be setup this way:

In a typical site, you will notice the url with http GET are written in this format

http://yoursite.com?key1=value1&key2=value2

Now in your hashbang, your will want to transform

http://yoursite.com#value1&value2

into beautiful url

http://yoursite.com#!key1=value1&key2=value2

Best way to develop a dynamic website

Thu Dec 20, 2012

The develop a dynamic website, with all those smooth page transitions similar to gmail. As per design we will use Bootstrap, Bootstrap provides all the css tools you need to setup a quick website.

Frontend skills you will need
- javascript
- html

Frameworks
First of all we will start of with a model view controller + observer design patterns to achieve a maintainable site.
The web frameworks that we will use are
- backbone js , giving a "structure" to the code
- require js , setting up javascript dependencies, works like php include
- mustache , page templates
- jquery , dom manipulations

as font icons we can get them for free at fontello, their package includes font-awesome

Folder Structure

  
        index.html
        css/
        templates/      <=== contains the html templates
        js/views/   <=== responsible for inital html materials and listenes to model changes / actions / events
        js/models/  <=== responsible for data models
        js/controller/  <=== defines the site routes
        blueprints/     <=== contains all the 3rd party library

To setup hashbang (similar to gmail) for page manipulations, there is a backbone module - backbone router. Using backbone router we can set up page to change dynamically depending on the hashbang setup. To let your hash bang searchable / crawable, checkout this post.

You can checkout the Boiler Plate i've setup using this structure for off the shelve deployment.

Further Readings
Backbone Router
- http://backbonetutorials.com/what-is-a-router/

Backbone + MVC
- http://backbonetutorials.com/organizing-backbone-using-modules/
- http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/
- http://blog.andyet.com/2010/oct/29/building-a-single-page-app-with-backbonejs-undersc/
- http://backbonetutorials.com/what-is-a-model/