Getting started with the offline-aware web
Offline world
http://commons.wikimedia.org/wiki/File:Train_entering_tunnel_at_Hole_Head,_Holcombe_-_geograph.org.uk_-_370778.jpg
Offline-aware web?
http://www.flickr.com/photos/seandreilinger/133276854/sizes/m/in/photostream/
Possibilities for the offline world
- Remember last visited slide of your presentation.
- Remember last selected field values in a form.
but also…
- Keep user profile locally.
- Store user preferences.
- Save user actions history.
- Enable some functionality offline.
localStorage
This specification defines an API for persistent data storage of key-value pair data in Web clients.
- Persistent (vs. sessionStorage)
- No cookies needed (and more space offered)
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.
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!
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
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 in your browser — Chrome
Alternatives to localStorage
Keep in mind:
localStorage IS NOT a database
WebSQL
SQL Database Model
Using Sqlite syntax (3.6.19)
http://caniuse.com/#feat=sql-storage
W3C DEPRECATED
IndexedDB
NoSQL Database Model
http://caniuse.com/#feat=indexeddb
W3C SUPPORTED - DRAFT
localStorage polemics
- Synchronous - Other scripts below wait until finish
- Concerns about disk I/O performance
- People abusing it
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?
http://www.flickr.com/photos/rosengrant/3681001732/sizes/m/in/photostream/
We cannot rely on browser's default cache!
Appcache
- What do we need to save locally?
- Which files make sense only if we are online?
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
- Appcache is domain specific
- For turning changes live, appcache needs modifications
- You can edit comment line for updating appcache
- Disable appcache when developing
Clean appcache in Chrome
chrome://appcache-internals
Detecting when offline
windows.navigator.onLine
Problem:
NON-RELIABLE!
Only detects well if users switch online/offline browser option
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!
http://www.flickr.com/photos/metrocincinnati/4399059080/sizes/m/in/photostream/
Offline-aware application example
Softcatalà translator