THE OFFLINE WEB

CouchDB +
PouchDB
Building a more capable web
"A web based OS, but then it wont work offline?"
Gmail Offline
Thunderbird Offline
Why care?
Thinking outside the
bubble, the world doesnt have ubiqutious internet.
Why care?
That mobile thing got
popular huh?
Why care?
Performance, offline is like, really fast
Why care?
Reliability and Trust
Why care?
Robustness, server downtime doesnt mean your app is unavailable
Why care?
- Privacy
- Security
- Peer to Peer functionality
- .... and more
Delivering the best
user experience
SOLD!
But how does it work?
Different applications will have different approaches
Difficulty rating: meh
Warn the user they are
offline
Difficulty rating: hard
Provide users cached data
Difficulty rating: very hard
Allow users minimal
interaction
Difficulty rating: like, super hard
Allow users full interaction with complex app
How do we make this work?
Packaged web apps
- Embedded Webkit
- Cordova
- Firefox + Chrome Apps
Service Workers
navigator.serviceWorker.register("/assets/v1/worker.js").then(
function(serviceWorker) {
console.log("success!");
serviceWorker.postMessage("Howdy from your installing page.");
}, function(why) {
console.error("Installing the worker failed!:", why);
}
);
http://www.w3.org/TR/2014/WD-service-workers-20140508/
localStorage
localStorage.myData = 'quick brown fox';
- Good for small settings
- Has to be a string
- Synchronous, blocks page
IndexedDB
var trans = db.transaction(["todo"], "readwrite");
var store = trans.objectStore("todo");
var request = store.put({
"text": todoText,
"timeStamp" : new Date().getTime()
});
- Powerful, but complicated
- Implementations still somewhat different
- Likely want to use a wrapper
So I am ready to go? that didnt seem so hard ...
Offline apps require a
different architecture
May be tempted to
degrade when offline
addEventListener('submit', function() {
request.post('/create/thing/', function (err, res) {
if (err) {
retryPost();
}
showNewThing();
});
});
Hope for the best, plan for the worst
Solution: put all the state in the client, sync data when possible
now you have
N-1 problems
Syncing data is hard
- Want to sync changes asap
- Transfer the minimal amount of data
- Handle unreliable networks
- Deal with conflicting changes
You do not want to write your own protocol
Things took 2 years to write sync for their todo list
Email and calendar have their own protocol
You do not want to use those protocols
PouchDB takes CouchDBs storage + replication and puts it in the browser
Stores data locally and syncs in the background
Basic database API
var db = new PouchDB('name');
db.post({'some': 'data'});
db.sync('http://myserver.com/database', {live: true})
db.changes().on('change', function() {
console.log('Ch-Ch-Changes');
});
Dont care where events come from
elem.addEventListener('submit', function() {
db.put(formData);
});
db.changes().on('change', function() {
updateUI();
});
Data holds the state
db.post({
'type': 'email',
'subject': 'KITTENS!'
'state': 'unsent'
});
On the server:
db.changes().on('change', function(change) {
var doc = change.doc;
if (doc.type === 'email' && doc.state === 'unsent') {
sendEmail(doc, function (err, res) {
if (err) {
doc.failed = true;
doc.error = err.message;
} else {
doc.state = 'sent';
}
db.put(doc);
}
}
});
Conflicts
decided by the app
function mergeConflicts(docs) {
var result = {};
docs.forEach(function(doc) {
extend(result, doc);
});
return result;
}
To Surmise
- Make your application work offline, its the right thing to do.
- Dont write your own sync protocol, its crazy
- Haggis exist