What we've seen so far

JavaScript on the server:

  • Node.js, event-driven server-side JavaScript
  • Frameworks and tools like Express and Connect

Client-side JavaScript MV* frameworks:

  • Lower-level frameworks like Backbone and the YUI App Framework
  • Highly abstracted (MVVM and others) frameworks like Ember and Knockout

One language, client and server

  • But are we really using them effectively?
Instead of coding in one language, we're actually coding in two. One is the subset [of] JavaScript that can be run in all browsers, and another is the set of JavaScript that can be run by Node.
Eric Florenzano

Stepping Back: A History of Web Frameworks

Highly abstracted server MVC frameworks gain popularity

  • Ruby on Rails (2004)
  • Django (2005)
  • CakePHP (2005)

Rendering is done on the server, and outputs HTML

Stepping Back: A History of Web Frameworks

Client-side MV* frameworks gain popularity

  • Knockout.js (2010)
  • Backbone.js (2010)
  • Ember.js (2011)

Server outputs JSON, and the client renders the data into HTML

Client-side Frameworks

Benefits:

  • AJAX techniques and JS animations provide a more responsive experience
  • Separation of concerns: server provides data, client handles layout

Drawbacks:

  • Limited possibilities for SEO and accessibility
  • Initial rendering with JavaScript slows down time to first interaction

Real world example: Twitter

A failed client-side render of Twitter
source: Paul Stainthorp (Flickr: pstainthrop)
...We've been working to take back control of our front-end performance by moving the rendering to the server. This has allowed us to drop our initial page load times to 1/5th of what they were...
Dan Webb
Twitter Engineering Manager

The Best of Both Worlds

JavaScript Client/Server Frameworks

Render the first page load completely on the server

  • Fast server-side rendering: time to first interaction is cut
  • Allows search engines to index your page for SEO purposes
  • Progressive enhancement: site works even without JavaScript enabled

Incrementally update sections of the page through client-side rendering

  • Keeps the native-application-like responsiveness
  • Even more: Model representations can be shared between client and server

Sharing Mojito Models among Clients and Server

/* File name: WeatherModel.common.js */
YUI.add('WeatherModel', function(Y, NAME) {

    Y.mojito.models[NAME] = {

        /* Client and server code can both use the same 'fetch' method to get data */
        fetch: function(location, callback) {
            var query = 'SELECT * FROM weather.forecast WHERE location=' + location;

            Y.YQL(query, function (response) {
                /* Parse the data from the response here */
                callback(error, data);  
            });
        }
    };

}, '0.0.1', {requires: ['yql', 'jsonp-url']});

Battle of the Frameworks

Three major client/server frameworks as of September 2012

  • Mojito
    • Specializations:
      • Progressive enhancement, device-specific views, internationalization
  • Derby
    • Specializations:
      • Real-time collaborative applications, advanced conflict resolution
  • Meteor
    • Specializations:
      • Real-time applications, same abstracted API on client and server

Device Specific Views in Mojito

<html>
  <head>
    <title>Default View</title>
  </head>
  <body>
    <div id="{{mojit_view_id}}" class="mojit">
      <h2>Hi {{name}}, it looks like you're visiting us from a regular browser!</h2>
    </div>
  </body>
</html>
<html>
  <head>
    <title>iPhone View</title>
  </head>
  <body>
    <div id="{{mojit_view_id}}" class="mojit">
      <h2>Hi {{name}}, it looks like you're visiting us from an iPhone!</h2>
    </div>
  </body>
</html>

Advanced Conflict Resolution in Derby

Derby's model synchronization engine: Racer

A chat application in Derby

Experimental OT Techniques in Derby

  ## Use experimental operational transformation plugin in Racer ##

  racer.use require 'racer/lib/ot'

  ## Operational transformation text insertion ##

  model.on 'otInsert', '_room.text', (pos, text, isLocal) ->
    return if isLocal
    replaceText editor.value[...pos] + text + editor.value[pos..], (cursor) ->
      if pos <= cursor then cursor + text.length else cursor

  ## Operational transformation text deletion ##

  model.on 'otDel', '_room.text', (pos, text, isLocal) ->
    return if isLocal
    replaceText editor.value[...pos] + editor.value[pos + text.length..], (cursor) ->
      if pos < cursor then cursor - Math.min(text.length, cursor - pos) else cursor

Same Database API, Client and Server, in Meteor

Use the same familiar MongoDB API whether you're on the server or client.

// Publish all room documents, and per-room messages
Meteor.publish("chatrooms");
Meteor.publish("messages", function (room_id) {
  return Messages.find({room: room_id});
});
// Subscribe to all rooms, and messages in the first room
Meteor.subscribe("chatrooms");
Meteor.subscribe("messages", Chatrooms.find()[0]._id);

Packaging and Deployment in Meteor

Meteor contains its own packaging system to quickly install dependencies.

        # Use jQuery and Backbone within your Meteor application
        $ meteor add jquery backbone

        # Remove Twitter Bootstrap from your Meteor application
        $ meteor remove bootstrap
      

It also provides an infrastructure to quickly deploy your application online.

        # Quickly deploy to a Meteor domain
        $ meteor deploy myapp.meteor.com

        # Or set a CNAME and deploy to your own
        $ meteor deploy www.myapp.com
      

Using Mojito, Derby, and Meteor Today

Who's using these frameworks today?

  • Mojito
    • Currently used in production at Yahoo! in products such as Yahoo Axis!
  • Derby
  • Meteor
    • Currently used in production at the Meteor platform site
    • Note: Security flaws in the stable Meteor branch exist, but are being fixed

<Thank You!>

You can find me online in the following places: