Ido Green

Designing & Building

Great Web Applications

  -   Crested Butte, CO

Of course we're using Geolocation!
  • Launched in June, 2011
  • Over 1 million unique users
  • 2.5 times more likely to subscribe
  • Drove digital subscriptions to beyond 250,000
  • In January 2012, Financial Times bought Assanka
  • Simplifying development with the web app as the basis for all platforms

Defining the modern web app

The Power Of HTML5
Native & Desktop Experiences
Modern Web Apps

Tying It All Together

Designing modern web apps

  • Does it cost more to support browser X than it generates?
  • Is the browser older than the mayo in your fridge?
  • Is an exorcist required to debug the app's behavior?

Be explicit about the browsers you support

MVC Frameworks - Prevent Spaghetti Code

MVC controller
view model

Best practices for a great app

Make it easy to try & use

Use responsive layout for different form factors

Media Queries for Style Sheets

<link rel="stylesheet" media="all" href="/static/css/base.min.css" />
<link rel="stylesheet" media="only screen and (max-width: 800px)"
  href="/static/css/mobile.min.css" />

Testing CSS media queries in JavaScript with window.matchMedia()

if (window.matchMedia('only screen and (max-width: 480px)').matches) {
  // Asynchronously provide experience optimized for phone
} else if (window.matchMedia('only screen and (min-width: 481px) and ' +
                             '(max-width: 1024px)').matches) {
  // Asynchronously provide experience optimized for table or smaller screen
} else {
  // Asynchronously provide full screen experience

Allow for deep linking & single page navigation

function updateHash(push) {
  if (push) {
    var slideNo = curSlide + 1;
    var hash = '#' + slideNo;
    window.history.pushState(slideNo, 'Slide ' + slideNo, hash);
window.addEventListener('popstate', handlePopState, false);
function handlePopState(event) {
  if (event.state != null) {
    curSlide = event.state - 1;

Make it work offline

Use a primarily client side architect model for your app

Server side rendering doesn't work very well when offline!

Application Cache to enable the offline scenario

<html manifest="cache.appcache">

Store and cache data on the client

window.requestFileSystem(PERSISTENT, 1048576, initFs, fsError);
var idbRequest ='Database Name');
localStorage["key"] = "value";

Persist users data

var elems = document.querySelectorAll("textarea, input");
var len = elems.length;
for (var i = 0; i < len; i++) {
  var elem = elems[i];
  elem.addEventListener("input", function(item) {
    localStorage[formName + "-" +] =
    var debug = document.getElementById("data-persistence-debug");
    debug.innerHTML = "Last auto-saved at: " + new Date();
  }, false);

LawnChair - simple json storage

Let the user tell you what they want

<input type="text" x-webkit-speech />
function startSearch(event) {
        if ( > 1) {
          var second =[1].utterance;
          document.getElementById("second_best").value = second;

Treat performance like a feature

Use Application Cache to provide local caching

<html manifest="cache.appcache">

Store data locally

window.requestFileSystem(PERSISTENT, 1048576, initFs, fsError);
var idbRequest ='Database Name');
localStorage["key"] = "value";

Use CSS3 transitions, transforms and animations

transition: all 1s ease-in-out;

Use WebWorkers for non-blocking JavaScript

var worker = new Worker('myworker.js');

More great tips at

It should all just work, right?

Chrome Frame

<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">

One last thing...

Aim for a great experience, everything else will follow.




The web is what you make of it.