Getting started with the offline-aware web

Toni Hermoso Pulido

@toniher

2012-03-14

@webcatBCN

Offline world

Train enters tunnel http://commons.wikimedia.org/wiki/File:Train_entering_tunnel_at_Hole_Head,_Holcombe_-_geograph.org.uk_-_370778.jpg

Offline-aware web?

Texting in train http://www.flickr.com/photos/seandreilinger/133276854/sizes/m/in/photostream/

Possibilities for the offline world

but also…

localStorage

This specification defines an API for persistent data storage of key-value pair data in Web clients.

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

What is localStorage?

Hash, associative array, map, dictionary

Abstract data type composed of a collection of (key,value) pairs, such that each possible key appears at most once in the collection.

http://en.wikipedia.org/wiki/Associative_array

Hash in JavaScript

person['name'] = 'John Smith';

person['phone'] = '66123456789';

Basics of localStorage


	localStorage.setItem('name', 'John Smith'); // set a value

	localStorage.getItem('name'); // get a value

	localStorage.removeItem('name'); // remove a key / value
	

More on localStorage


	localStorage.length; // number of key - value pairs stored

	localStorage.clear(); // Clear all pairs
	

IMPORTANT: you can only have one hash!

Complex data in localStorage

IMPORTANT: you can only store strings!

Solution (I):

Stringify JSON

localStorage.setItem('person', JSON.stringify({name: 'J. Smith', phone: '66123456789'}));

var person = JSON.parse(localStorage.getItem('person'));
	

Complex data in localStorage

IMPORTANT: you can only store strings!

Solution (II):

Hack: Turn key parseable

localStorage.setItem('person-name', 'John Smith');

localStorage.setItem('person-phone', '+66 123 456 789');
        

Where can I use it?

Supported in many browsers!

Can I use LocalStorage

http://caniuse.com/#feat=namevalue-storage

If not, use Modernizr: apply CSS for hiding options, recur to polyfills…

Limitations - space

By definition up to ~5MB

However, many only up to 2.5 MB (Webkit)

Some tests

http://dev-test.nemikor.com/web-storage/support-test/

http://arty.name/localstorage.html

Limitations - different/same domains

http://example.com:80/
 
\       \         \_ port
   
\       \_ domain
   
\_ scheme

http://html5-demos.appspot.com/static/html5storage/index.html#slide14

Restricted to a protocol or a domain

http://example.com != http://www.example.com

http://example.com != https://example.com

BEWARE: at the same time, it can also affect other applicactions in the same domain.

Clean in your browser — Firefox

Clean LocalStorage Firefox

Clean in your browser — Chrome

Clean LocalStorage Chrome

Alternatives to localStorage

Keep in mind:

localStorage IS NOT a database

WebSQL

SQL Database Model

Using Sqlite syntax (3.6.19)

Can I use Web SQL

http://caniuse.com/#feat=sql-storage

W3C DEPRECATED

IndexedDB

NoSQL Database Model

Can I use IndexedDB

http://caniuse.com/#feat=indexeddb

W3C SUPPORTED - DRAFT

localStorage polemics

http://hacks.mozilla.org/2012/03/there-is-no-simple-solution-for-local-storage/

Are we offline-aware yet?

Do you think we are ready?

offline yet?

http://www.flickr.com/photos/rosengrant/3681001732/sizes/m/in/photostream/

We cannot rely on browser's default cache!

Appcache

Appcache example

Extension: .appcache

Content-Type: text/cache-manifest

CACHE MANIFEST
# 2012-03-10:v1.3.14

# Explicitly cached files
CACHE:
traductor.html
/css/mobile.css
/apertium/js/apertium_m.js
..
select.png

# Requires network, bypass cache
NETWORK:
/apertium/json/translate
http://stats.softcatala.cat/piwik.js

# If resource not accessible
FALLBACK:
/ warn.js

Appcache in HTML header

Link in header

<html manifest="example.appcache">
...
<html>

Appcache JS programing

var cache = window.applicationCache;

cache.addEventListener('cached', handleCacheEvent, false);
cache.addEventListener('checking', handleCacheEvent, false);
cache.addEventListener('downloading', handleCacheEvent, false);
cache.addEventListener('error', handleCacheError, false);
cache.addEventListener('noupdate', handleCacheEvent, false);
cache.addEventListener('obsolete', handleCacheEvent, false);
cache.addEventListener('progress', handleCacheEvent, false);
cache.addEventListener('updateready', handleCacheEvent, false);

// When a new manifest is successfully downloaded, swap the new cache and reload page.
cache.addEventListener('updateready', function(e) {
  if (cache.status == cache.UPDATEREADY) {
    cache.swapCache();
    if (confirm('A new version of this site is available. Load it?')) {
      window.location.reload();
    }
  }
}, false);

http://html5-demos.appspot.com/static/html5storage/index.html#slide40

Issues and tips

Clean appcache in Chrome

chrome://appcache-internals
Clean appcache in Chrome

Detecting when offline

Problem:

NON-RELIABLE!

Only detects well if users switch online/offline browser option

Reference about the problematics

Solution to detect when offline

Perform a HEAD request to a JSON within a certain timeout

var checkurl = "/dummy.json" + "?" + Math.random();
		jQuery.ajax({
                       url:checkurl,
                       type:"HEAD",
                       dataType:"json",
                       timeout:2000, //Wait 2 secs if connection problem
                       async:true,
                       success:function(data, status){
			//specific online action
                       },
                       error:function(x, t, m){
                        $('#warninternet').append('No connection!');
                       }
                });

Thanks for your attention!

Success mobile http://www.flickr.com/photos/metrocincinnati/4399059080/sizes/m/in/photostream/

Offline-aware application example

Softcatalà translator
#