Quick Overview

A history of web frameworks

Why are we moving to the server?

  • Benefits for users
  • Benefits for developers

How you can use this with your YUI code today

  • Or even any other JS framework!

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

The shift to a service-oriented architecture

Standardizing data access over HTTP

  • Process your data in the back-end: return as JSON/XML
  • Use the same source of data for both the web and for native apps

Example: YQL

        Y.YQL('SELECT * FROM search.suggest WHERE query="pie";', function (data) {
            // Work with your data here
        });
      
        NSDictionary *results = [yql query:@"SELECT * FROM search.suggest WHERE query='pie'"];
      
        http://query.yahooapis.com/v1/public/yql?q='SELECT * FROM search.suggest WHERE query="pie"'
      

Stepping Back: A History of Web Frameworks

Client-side MV* frameworks gain popularity

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

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

Problems with Client-Side Rendering

Performance

  • On slower mobile devices - time to initial content can be much slower

SEO Concerns

  • Server doesn't generate HTML - only JSON
  • Not all search engines can index the pages of your app

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

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 gives a good experience, even if not all JS is supported

Incrementally update sections of the page through client-side rendering

  • Keeps the native-application-like responsiveness

Problems?

Lots of code duplication if using two different languages

  • Not much shared code possible since they're not interoperable
  • Example: Write i18n code once in PHP for the server, and again in JavaScript for the client

Our solution:

  • Node.js

Node.js

JavaScript on the server:

  • Node.js, event-driven server-side JavaScript
  • Micro-frameworks like Express and Connect
  • Build tooling like Grunt

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

The Life of a HTTP Request

When a request comes in, what needs to happen?

HTTP Middleware
Server
Client
Both
Personalization
Route Handling
Resource Fetching
Formatting and Rendering
UI Binding

Sharing data between client and server

Express State

  • github.com/yahoo/express-state
  • Lets you share simple data between client and server
      // `app.expose` for exposing data globally on every route
      app.expose({
          api_key: '02348notreal2394879137872358bla'
      }, 'MY_APP.Flickr');

      // `res.expose` for exposing data on a single route
      app.get('/photos', function (req, res) {
          res.expose(req.photos, 'MY_APP.users');
      });
      

Route Handling

      // Map routes to unique names with `express-map`
      app.map('/users/', 'user-list');
      app.map('/users/:user', 'user-profile');

      // Expose routes as serialized objects on the client
      app.expose(app.getRouteMap(), 'MY_APP.routes');
      
      // `App.ROUTES` is available anywhere on the client
      console.log(MY_APP.routes);

      // Merge `App.ROUTES` with any client-only route data (not shown here)
      // and bootstrap it in your application.
      app.set('routes', MY_APP.routes);
      

Resource Fetching

Resource Models

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

                 return Y.YQLPromise(query).then(function (data) {
                      /* Parse the data from the response here */
                  });
              }
          };
      

Resource Fetching

Resource Bootstrapping

          app.get('/weather', function (req, res) {
              var weather = Weather.fetch().then(function (data) {
                  res.expose(data, 'Weather.DATA');
                  res.render('weather', {
                      weather: data
                  });
              });
          });
      
          // `Weather.DATA` is available anywhere on the client
          console.log(Weather.DATA);

          // Can be used to bootstrap a new model
          this.set('weather', new WeatherModel(Weather.DATA));
      

Formatting and Rendering

Share templates between client and server

Compile string-based templates like Handlebars into YUI modules

  • Use build-time tools like Grunt to compile templates in your build
  • Use tools like Locator to abstract using templates from any location

Use the `Y.Template` API to use templates in one way regardless of engine

          YUI.add('templates-foo', function (Y) {

              var engine = new Y.Template(Y.Handlebars),
                  precompiled;

              // Generated from the Handlebars compiler. This is the evaluated result of
              // precompiling `foo.handlebars`.
              precompiled = /* precompiled template interpolated here here */

              Y.Template.register('foo', engine.revive(precompiled));

          }, '0.0.1', {requires: ['template-base', 'handlebars-base']});
        

Summary

Moving front-end to the server is better for users

  • Faster load times and time to initial content
  • Still lets you have a modern JavaScript UI

Moving front-end to the server is better for developers

  • Sharing code reduces the amount of duplication in your application
  • Keeps presentation and business logic separate between your team

<Thank You!>

You can find me online in the following places: