UX Camp

Web Frontend Dev

Part 3 of 4: From the Trenches

Presented on 15 March 2013.

Press down for video or right for slides.

Presented by

John-Philip Johansson at Avanade

Tip: Watch in fullscreen. It's in HD.

Download: MP4 720p, MP4 480p, OGG 720p, or OGG 480p.


Rounding up the basics

Design patterns in JavaScript

Somethings from a project

Tips & tricks

Rounding up the basics

Some extra stuff we didn't cover so far

JavaScript functions



Curry functions

Safer constructors

Even safer constructors


Immediately Invoked Function Expressions

(function() {
  // do secret stuff


var buffer = {
  entries: [],
  add: function(s) {

var source = ["867", "-", "5309"];
source.forEach(buffer.add); // error: entries is undefined

source.forEach(buffer.add.bind(buffer)); // ok!

Curry functions

var simpleUrl = function(protocol, domain, path) {
  return protocol + "://" + domain + "/" + path;

var myPageUrl = simpleUrl.bind(null, 'http', 'spelkalendern.se');
myPageUrl('about') === 'http://spelkalendern.se/about';

Safer constructors

function User(name, passwordHash) {
  if (!(this instanceof User))
    return new User(name, passwordHash);

  this.name = name;
  this.passwordHash = passwordHash;

var user1 = new User('abc', '123'); // as expected
var user2 = User('def', '456'); // now also works!

Even safer constructor

function User(name, passwordHash) {
  var self = this instanceof User ? this : Object.create(User.prototype);

  self.name = name;
  self.passwordHash = passwordHash;

  return self;

var user1 = new User('abc', '123'); // as expected
var user2 = User('def', '456'); // now also works!

JavaScript arguments

Undefined arguments


Arguments object


Undefined arguments

var sum = sum(1, 2, 3, 4, 5);


send(url, [1, 2, 3, 4, 5]);

Arguments object

send( { url: url, data: [1, 2, 3, 4, 5] } );


// Seen something like this?
var alert = new Alert("Error", message, "blue",
                      "white", "black", "error", true);
// Prefer this instead
var options = { titleColor: "blue", bgColor: "white",
                textColor: "black", icon: "error", modal: true }
var alert = new Alert("Error", message, options);
// How to do it
function Alert(title, message, opts) {
  // ...
  var defaultOpts = { ... };
  opts = $.extend(defaultOpts, opts || {});
  this = $.extend(this, opts);

HTML semantics

<article>For what you would syndicate</article>
<section>For things that belong together</section>

<aside>For related side content</aside>
<nav>For pure navigation links</nav>

<header>At the start of areas</header>
<footer>At the end</footer>

Doesn't work in IE8 and below, but you can use html5shiv.

CSS Architecture





Scalable and Modular Architecture for CSS

h1             /* Base   */

.l-line        /* Layout */

.mod-tooltip   /* Module */

.is-hidden     /* State  */

.highlight     /* Theme  */


Object-Oriented CSS

The Media object
screenshot of the media object
.media { margin: 10px; }
.media, .bd { overflow: hidden; _overflow: visible; zoom: 1; }
.media .img { float: left; margin-right: 10px; }
.media .img img { display: block; }
.media .imgExt{ float: right; margin-left: 10px; }


Blocks, Elements, and Modifiers

Blocks and Elements
Illustration of blocks and elements

Illustration of modifier

CSS Specificity

Use classes, avoid elements, don't use ID's

Right to left!

inline style > external

Don't be overly specific
.main .intro  /* later */
.main p.intro  /* even later */
section.main p.intro  /* uhoh... */
article section.main p.intro  /* I GIVE UP! */
p.intro /* bad */
.intro  /* good */
.main .intro /* ok */
.main-intro  /* better */
.intro { border: none !important; } /* probably wrong! */

Design Patterns

in JavaScript


  • Solves a particular problem
  • Does not have an obvious solution
  • Describes a proven concept
  • Describes a relationship

The Module Pattern

Enables private and public

Basic module

Not visible outside of scope function

(function () {

  var $title = $('article h1');
  var originalTitle = $title.text();

  var reverseString = function(s) {
    return s.split("").reverse().join("");

  $title.text( reverseString(originalTitle) );


Module-based class

var testModule = (function () {
  var privateVariable = 0;

  var privateFunction = function() { ... };

  return {
    publicFunction: function () { ... };

Revealing Module Pattern

var testModule = (function () {
  var privateVariable = 0;

  var privateFunction = function() { ... };

  var publicFunction = function() { ... };

  return {
    theFunction: publicFunction

Import modules

var testModule = (function ($, w, undefined) {
  // ...
})(jQuery, window);

Extend module

var testModule = (function ($) {

  $.newMethod = function() { ... };

})(jQuery = jQuery || {});

AMD, CommonJS, RequireJS, and ES Harmony

  module_id /*optional*/, 
  [dependencies] /*optional*/, 
  definition function /*function for instantiating the module or object*/
define('myModule', // optional
  ['math', 'graph'], // optional
  function ( math, graph ) {
    var isReady = false, foobar;

    // note the inline require within our module definition
    require(['foo', 'bar'], function (foo, bar) {
        isReady = true;
        foobar = foo() + bar();

    // Note that this is a slightly different pattern
    // With AMD, it's possible to define modules in a few
    // different ways due as it's relatively flexible with
    // certain aspects of the syntax
    return {
      plot: function(x, y){
        return graph.drawPie(math.randomGrid(x,y));

Observer vs. Pub/Sub

Observer pattern

Publisher / Subscriber pattern

Observer pattern

Requires knowledge of the object that notifies

// observe
$('.myModule').bind('eventName', myCallback);

// notify

Publisher / Subscriber pattern

Uses 'channels' so no knowledge of origin is needed

// subscribe
$(document).on('namespace/eventName', myCallback); // put it on the root

// publish
$(document).trigger('eventName'); // doesn't matter much what element

Facade pattern

Limited abstractions of methods

Seen a lot in jQuery

// same as
$('.myClass').on('click', myCallback);

Factory pattern

Generic interface for creating objects

Great when serializing

function Car() { ... };
function Truck() { ... };

function VehicleFactory() {};
VehicleFactory.prototype.createVehicle = function ( options ) {
  if( options.vehicleType === "car" )
    this.vehicleClass = Car;
    this.vehicleClass = Truck;

  return new this.vehicleClass( options );

Somethings from a project

Some useful jQuery methods


Missing and Exists

if ($('.aClass').exists())
  // do something
if ($('.someClass').missing())

Serialize form to object

var formData = $('form').serializeObject();
$.post(url, formData);

Manipulate URL parameters

// read
var sort = $.urlParam('sort');

// write
$.urlParam('sort', 'ascending');

Combine objects

var diff = $.difference(obj1, obj2);

var intersection = $.intersect(obj1, obj2);

var union = $.union(obj1, obj2);

var symDiff = $.symmetric(obj1, obj2);

Debug flag

Enable debug methods in your code

// page init, not included in production code
if ( urlParam('debug') === 'true' )
  MyLib.debug = true;

// then in your code
if ( MyLib.debug )
  // do stuff

Time functions

Expose debug functions

Check AJAX results

Enable offline-mode

Styling flags


Switch CSS files with a flag

Highlight specific elements

Enable live edit


Basic idea



No knowledge of outside components

Little knowledge of inside components

Basic "inheritance"


Ajax action - tooltip input

  actionText="Create New group"
  inputText="New group name"
  postUrl="/api/groups/" />

Component example 1 Component example 2 Component example 3


One HTML file

One or zero CSS files

One or zero JS files

Follow a strict naming convention


The JS warns if needed elements are missing

The JS warns if the AJAX isn't as expected

Components - example of self check

Tips & tricks


Perceived performance

Optimize caching

Minimize round-trip times

Minimize request overhead

Minimize payload size

Optimize browser rendering

Performance tools

Test your page with:

Google Page Speed

Yahoo! YSlow


Compress (lossless!) your images with Smush.it

Use the Network console and Profiler in Chrome dev tools

Pretend privacy

var myObj = {};
myObj._private = 'ssssh';

Cascade / Chaining

Return 'this' instead of 'undefined'

Chaining in jQuery

Typical (don't do this)


At least do this

var $mainContent = $('div.main-content');


Preferably use chaining

var $mainContent = $('div.main-content');


How to do chaining

// taken from the actual jQuery source
  addClass: function( value ) {
    // ...

    return this;


AKA deferred or future


$.getJSON(url, data, onDone);

Using promises

$.getJSON(url, data).done(onDone);

Do your own by calling jQuery.Deferred()

Do's and don'ts

No inline JavaScript

No inlince CSS

CSS on top, JS on bottom of the page

Consider font-icons

Consider image sprites

Use a reset.css or normalize.css

Optimize your images

Pick a coding style and stick with it

Keep URL's out of JS, use data-attributes in HTML if needed

A tip on responsive web design

Illustration of responsive web design

Design a handful of reflows, and stick to them.

Dev flow

The browser console

Fast feedback

Easy online checks

The browser console

<3 it

Not just console.log, use .dir and .error too

Quickly test your scripts

Verify JS behaviour

Fast feedback

Your changes should be instantly visible


Easy online checks

Simple hosting - Dropbox with bit.ly

Online editors - CodePen or jsFiddle


Some videos,

a few frameworks,

and a bunch of books

JavaScript, wat?

Hilarious 4min presentation of JS uirkiness!

View it here.

50 performance tricks

to make your HTML5 apps and sites faster


DOM, HTML5, & CSS3 Performance

Web Application Development Workflow

How Web Browsers Work



Twitter Bootstrap

Zurb Foundation

HTML5 Boilerplate



book cover book cover book cover book cover book cover

the End?


I got one: do you want a talk on functional programming?