JS
Everywhere

~1000

1 to 20+ connectors - Different charging capacity

Different connector types - Time limit - Free / Non-free

Payment type - Geoposition - Etc. etc...

Server Side

Sorry; your browser does not support svg!

Sorry; your browser does not support svg!

http://nodejs.org/
A simple http server
var http = require('http');

http.createServer(function(request, response) {    
    response.writeHead(200, {'Content-Type': 'text/plain'});
    response.end('Hello World\n');
}).listen(8080, '127.0.0.1');

V8 - async model

Non-blocking

Does not use OS threads

HTTP is first class

Slowly Changing
Data

Data synchronization

Sorry; your browser does not support svg!

Real Time
Data

Traditional XHR

Sorry; your browser does not support svg!

HTTP Load

60s / 20s = 3rpm * 60 = 180rph

100users * 180rph = 18000rph

180rph - 10updates = 170rph waste * 100users = 17000rph waste

What if we pushed?

10updates * 100users = 1000mph

Server Sent Events

Sorry; your browser does not support svg!

http://www.w3.org/TR/eventsource/

Why SSE?

Why not WebSockets or LongPolling?

No need for full duplex

Mobile network proxies

Automatic reconnect

Scaling

Sorry; your browser does not support svg!

Sorry; your browser does not support svg!

http://redis.io/

noSQL

Key-value store

Can do pubsub

Sorry; your browser does not support svg!

Deployment

Client Side

Native
vs.
Web

It depends

App
vs.
Web Site

It depends

Vanilla.js

No jQuery. No Sencha. Nothing. Nada.

Query Selecting

A huge part of jQuery <1.8 is Sizzle:

$('div .foo');

Native in browsers:

document.querySelectorAll('div .foo');
Serialization and De-serialization

Parsing JSON:

$().parseJSON({"my":"object"});

Native in browsers:

JSON.parse({"my":"object"});
Animations
$("a").hover(function(){
    $(this).stop().animate({ paddingLeft: '50px', 
                             backgroundColor: '#efefef', 
                             color : '#333' }, 500);
}, function() {
    $(this).stop().animate({ paddingLeft: '25px', 
                             backgroundColor: '#ffffff', 
                             color : '#afafaf' }, 500);
});
a {
    transition-property: color, background-color, padding-left;
    transition-duration: 500ms, 500ms, 500ms;
}

a:hover {
    background-color: #efefef;
    color: #333;
    padding-left: 50px;
}
Data transport
var xhr = false;

if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    try {
        xhr = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (error) {
        try {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (err) {
            xhr = false;
        }
    }
}

if (xhr) {
  xhr.open('GET', 'xhr.json', true);
  xhr.onreadystatechange = function() {
      if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.responseText);
      }
  };
  xhr.send();
}
Data transport
var xhr = new XMLHttpRequest();

xhr.open('GET', 'data.json', true);
xhr.onloadend = function(obj) {
    console.log(obj.target.responseText);
}

xhr.send();
Better DOM API's

Plain DOM:

<div id="foo">

  <p>bar</p>
</div>

DOM Level 1:

var el = document.getElementById('foo');
el.firstChild; // null???

Element Traversal Specification:

var el = document.getElementById('foo');
el.firstElementChild;
http://www.w3.org/TR/ElementTraversal/

No UA sniffing

No server side detection.

Feature detection
var support = {
    localStorage : !!(window.hasOwnProperty 
                      && window.hasOwnProperty('localStorage')),
    geoLocation  : !!navigator.geolocation,
    touchEvents  : (typeof (document.createTouch) !== 'undefined')
}

if (support.localStorage) {
    // Save or read from local storage

} else {
    // No storage :/ Do something else

}
http://modernizr.com/

Basics

Viewport:
<head>
  <meta charset="utf-8">
  <meta name="viewport" 
        id="viewport" 
        content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,initial-scale=1.0">

</head>
http://dev.opera.com/articles/view/an-introduction-to-meta-viewport-and-viewport/
Easy width/height
.foo {
    width: 600px;
    border: 5px solid black;
} /* Total width 610px */
* {
    box-sizing: border-box;
}

.foo {
    width: 600px;
    border: 5px solid black;
} /* Total width 600px */
Media Queries
.el {
    display: none;
}

@media screen and (min-width: 768px) and (max-width: 1024px) {
    .w1024 { display: block; }
}

@media screen and (min-width: 480px) and (max-width: 768px) {
    .w768 { display: block; }
}
<div class="el w1024">1024</div>
<div class="el w768">768</div>
Retina Detection
.image {
    background-image: url('../gfx/hdpi.image.png');
}

@media screen and (min-device-pixel-ratio : 1.5) {
    .image {
        background-image: url('../gfx/hdpi.image.png');
        background-size:  30px 30px;
    }
}
Structure
#head, #main, #foot {
    position:   absolute;
    overflow:   hidden;
    width:      100%;
}
#head {
    top:        0;
    height:     30px;
}
#main {
    top:        30px;
    bottom:     40px;
}
#foot {
    bottom:     0;
    height:     40px;
}
<div id="head">head</div>
<div id="main">main</div>
<div id="foot">foot</div>
Structure - Scrolling
#head, #main, #foot {
    position:   absolute;
    overflow:   hidden;
    width:      100%;
}
#head {
    top:        0;
    height:     30px;
}
#main {
    top:        30px;
    bottom:     40px;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
}
#foot {
    bottom:     0;
    height:     40px;
}
<div id="head">head</div>
<div id="main">main</div>
<div id="foot">foot</div>
Structure
<div id="head">head</div>
<div id="main">main</div>
<div id="foot">foot</div>
<script src="scroll.js"> </script>
var support = {
    nativeScroll : return typeof this.docEl.style.webkitOverflowScrolling === 'string'
}

if (support.nativeScroll) {
    // Append JavaScript based scrolling
}
http://cubiq.org/iscroll
Click delay
element.addEventListener(support.touch ? 'touchend' : 'click', function(event) {
    // Do something on click / touch
});
Hardware acceleration
.selector {
    -webkit-transform: translate3d(0,0,0);
}
DOM is sloooooooooowwww...
var i   = 100, li, txt,
    ul  = document.getElementById('ulElement');

while(i--) {
    li  = document.createElement('li');
    txt = document.createTextNode(i);
    li.appendChild(txt);
    ul.appendChild(li);
}
var i   = 100, li, txt,
    ul  = document.createDocumentFragment('ul');

while(i--) {
    li  = document.createElement('li');
    txt = document.createTextNode(i);
    li.appendChild(txt);
    ul.appendChild(li);
}

document.body.appendChild(ul);
Running in app mode
var url = 'http://m.chargelizer.com';
if (window.location.host) {
    url =  window.location.protocol + '//' + window.location.host;
    if (window.location.pathname !== '/') {
        url += window.location.pathname;
    }
}

var xhr = new XMLHttpRequest();
xhr.open('GET', url + '/data.json', true);

Deployment

Sorry; your browser does not support svg!

https://build.phonegap.com/

Thnx!

@trygve_lie