The Offline Web

by Dale Harvey / @daleharvey

Offline ..... Web?

The web is becoming an application platform

Why Offline?

because offline ....

Why Offline?

because .... performance!

Why Offline?

because .... failure tolerance

Why Offline?

because ....

  • Privacy
  • Peer to Peer

Sold!

So how does this all work?

Static Site
vs
Single Page Applications
vs
Web App

AppCache

Mostly only a pain in the ass

Example Appcache:

CACHE MANIFEST
# Mon May 18 2015 07:53:07 GMT+0000 (UTC)
/
/activity.html
/index.html
/install.html

/js/bundle.js
/style/icons/app-32.png
/style/icons/close.png
/style/icons/loading.png

NETWORK:
*

Cache invalidation,
easy right?

window.applicationCache.addEventListener('updateready', function(e) {
  if (window.applicationCache.status ==
        window.applicationCache.UPDATEREADY) {
    window.location.reload();
  }
});

Caches all the way down

Single Page Applications

<html><script src="framework.js" /></html>

LocalStorage: the good

localStorage.someData = 'foo';
localStorage.someData;
> "foo";

LocalStorage - the bad

localStorage.someData = {'a': 'b'};
localStorage.someData;
> "[object Object]"

localStorage.someData = JSON.stringify({'a': 'b'});

LocalStorage

  • Sync API + Encoding can be slow and block the UI
  • No indexes or ability to query
  • Limited Storage (2MB - 5MB)

WebSQL

var db = openDatabase('test', '0.1', 'A Database', 1024 * 1024);

db.transaction(function (t) {
  t.executeSql('CREATE TABLE IF NOT EXISTS table (id INTEGER, name TEXT)');
  t.executeSql('INSERT INTO table (name) VALUES (?)', ['FOO']);
  t.executeSql("SELECT * FROM table", [], function(result) {
    // results...
  });
});

WebSQL

  • Deprecated! Never supported in IE or Firefox
  • Buggy and unsupported

IndexedDB

var open = window.indexedDB.open('database', 1);

open.onupgradeneeded = function(e) {
  var db = e.target.result;
  var store = db.createObjectStore('store', { keyPath: 'id' });
  store.transaction.oncomplete = function() {
    var txn = db.transaction('store', 'readwrite')
        .objectStore('store').add({
      id: 'someData',
      foo: 'bar'
    });
  };
};

IndexedDB

  • Complex API
  • Mostly good browser support, but not 100%

You probably dont want to use IndexedDB directly

localForage

db.js

YDN

levelDown

So we can store things now, finished?

Preload

When you wake up to your daily commute on the tube / underground it would sure be nice to get through your morning emails

Filtered / Selective Sync

Spotify cant download the entire catalogue of music on every device, need to be able to pick which content to sync

Updates and Deltas

It would be good to notify the user when new content is available, cant feasibly redownload all synced data on updates

Conflict Resolution

I dont want my user to be losing data when they change the same data on seperate devices

Email === POP/IMAP

Calendars === CalDAV

You === ?

Sync Libraries

  • Ember Sync
  • Js Git
  • Mozilla makeDrive

Sync Libraries

PouchDB!

Provide an API to store data locally

var db = new PouchDB('database');

db.put({
  _id : 'someData',
  foo: 'bar'
});

db.allDocs().then(function(result) {
  // result ...
});

Syncs to remote server

var db = new PouchDB('db');
db.sync('http://example.org/cloud/db');

The Future: Service Workers

Offline by default?

TAKK :)