Render views fast in a modular web app

Daniel Hug

What I want in a Single-Page web App

  • speed: better than templating.
  • modularity: better than frameworks
  • scalability: Don't Repeat Yourself!

Templating

The goal:


renderItem({
    title: 'eggs',
    quantity: '1 dozen'
});
                    

The template:


The downsides of templating


var templateSrc = $('#item-template').html();
var getItemSrc = Handlebars.compile(templateSrc);

var $shoppingList = $('#shopping-list');
function renderItem(item) {
    var itemSrc = getItemSrc(item);
    $shoppingList.append(itemSrc);
}
                    
  • output is a string so elements must be queried to obtain their references
  • Updates to state refresh the whole template

Simplify with jQuery


function renderItem(item) {
    var $li = $('li').text(item.title + ': buy ' + item.quantity);
    $shoppingList.append($li);
}
                    
  • element references :)
  • To change a prop we must still re-render everything :(

Observable Objects: Snoopy

github.com/daniel-hug/snoopy


function renderItem(item) {
    var $li = $('<li>');
    item.snoop('title quantity', function(title, quantity) {
        $li.text(title + ': buy ' + quantity);
    });
    $shoppingList.append($li);
}

var eggs = new Snoopy({
    title: 'eggs',
    quantity: '1 dozen'
});
renderItem(eggs);
                        
  • element references :)
  • eggs.set('quantity', '2 dozen');
    won't refresh entire view.
Snoopy demo on jsbin.com

Smart data-binding: DOM Builder

github.com/daniel-hug/dom-builder


function renderItem(item) {
    var li = dom({ el: 'li',
        kids: [item.snoop('title'), ': buy ', item.snoop('quantity')]
    });
    $shoppingList.append(li);
}
                        
  • a view rendering module
  • accepts an observe function in place of any value to have it be live-bound to the state
  • updates only the necessary parts of the view without diffing
DOM Builder + Snoopy demo on jsbin.com

Keep a list: Observable Array

github.com/daniel-hug/observable-array


// create an observable array
var nums = new ObservableArray([1, 2, 3]);

// Get notified when it changes
nums.on('push', function() {
    console.log('new values: ' + [].join.call(arguments));
});

// add 2 items
nums.push(4, 5);
                        
  • get notified when items are added or removed
Observable Array demo on jsbin.com

Map the array to the DOM: DOM Array

github.com/daniel-hug/dom-array


// create an observable array
var nums = new ObservableArray([1, 2, 3]);

var listView = new DomArray(nums, $('ul')[0], function(num) {
    return $('<li>').text('number: ' + num);
});

// add 2 items
nums.push(4, 5);
                        
Observable Array + DOM Array demo on jsbin.com

Thank you!

Where to find me: