Working Offline with HTML5 web apps
with tips and trips for
Firefox OS
Hi! I'm Francisco Jordano
@mepartoconmigo
arcturus
The story ...
No more cable!
The story ...
Lots of new devices
The story ...
and all of them running stunning browsers!
The story ...
... but this is happening quite often
The London Underground problem
We have WiFi connection in each station
The London Underground problem
but we lose it when the train leaves the station
Try to avoid this
For this
What are we going to talk about?
80% things you apply to the web
20% optimisations and Firefox OS specific
What are we going to talk about?
We can tackle this problem with:
CONNECTIVITY DETECTION
and
CLIENT SIDE STORAGE
Are we online yet?
Losing connection happens more often than we expect
Are we online yet?
Check it!
//navigator.online;
if (navigator.onLine) { alert('online'); } else { alert('offline'); }
Are we online yet?
Listen for changes in the connection
window.addEventListener('offline', function onOffline() {
// We are offline
});
window.addEventListener('online', function onOnline() {
// We got the connection back
});
Are we online yet?
DEMO
Are we online yet?
Unfortunately we have some problems:
Doesn't give information about why we are offline
What Firefox OS is doing?
Better messaging
What Firefox OS is doing?
Example of online/offline detection
Store all the things!
We can save our relevant content on the client side
to play later with it
Let's remember how many ways of storing locally we have
A really old friend
- We can save up to 4KB
- Modified locally and server side
- Have expiration date
- They are damn fast
but
- Can be modified server side
- We send them with each request
The new kid on the block
LocalStorage
- Seriously, is all around, supported in all browsers
- Simple interface key/value
- Different default limits by browser (2.5, 5 and 10 MB)
- Doesn't has expiration
localStorage.myKey = myValue;
- Cannot be accessed by workers
- Funny implementation: http://www.filldisk.com/
- Can store just strings
- But the most important, it's SYNCHRONOUS!
IndexedDB to the rescue!
- It is asynchronous!
- It's versioned!
- It's transactional!
- Support indexes for faster searches!
- Offers bigger space (5 to 50 MB) and can be surpassed if user agrees
- ... but ...
- Well supported, but still missing some browsers :(
- Low level API
- 'Complicated' learning curve
IndexedDB example
Opening a connection with the database
var myDB; var request = window.indexedDB.open("MyBookShop", 1); request.onsuccess = function onSuccess(event) { myDB = event.target.result; };
request.onerror = function onError(event) {
alert('Sorry, cannot open the DB');
};
IndexedDB example
We do have versioning! \o/
// Once opened the connection
request.onupgradeneeded = function onUpgradedNeeded(event) { var db = event.target.result; var oldVersion = event.oldVersion; // Apply any schema upgrade if needed createSchema(db); };
IndexedDB example
We create object stores and indexes for searches
function createSchema(db) { // { 'isbn' : <String> (primary key),
// 'title' : <String>, // 'date' : <Date>, // 'author' : <String>, // 'cover': <Blob> // } var objectStore = db.createObjectStore('books',
{ keyPath: 'isbn' });
// Search by title
objectStore.createIndex('title', 'title');
// Search by author
objectStore.createIndex('author', 'author'); }
IndexedDB example
We have transactions!
var transaction = myDB.transaction(['books'], 'readwrite');
transaction.onerror = function() { // Handle error };
transaction.oncomplete = function() { // Handle success };
var objectStore = transaction.objectStore('books');
objectStore.add(book);
And we save objects!
IndexedDB example
And we can use the indexes to perform searches
var objectStore = myDB.transaction('books').objectStore('books');
var index = objectStore.index('author'); index.openCursor().onsuccess = function(event) { var cursor = event.target.result; if (!cursor) {/* We finished */} // Process each object in cursor.value cursor.continue(); };
We can use a streaming approach to process data!
Long live to cursors!
WoW that was dense!
Yeah, a lot of stuff there isn't? Some people have some code to help us.
- DB.js : http://aaronpowell.github.io/db.js/
- JQuery : https://github.com/axemclion/jquery-indexeddb
- IDBWrapper: https://github.com/jensarps/IDBWrapper
- PouchDB : http://pouchdb.com/
even the guys from Firefox OS created their own utility:
Getting ready to work offline
Now we can save user's data locally.
Are we ready for that?
HTML5 AppCache
manifest.appcache
CACHE MANIFEST
# version 1.0
index.html
style.css
image.png
# Use from network if available
NETWORK:
*
# Fallback content
FALLBACK:
/ offline.html
HTML5 AppCache
Use it in your html
<html manifest="manifest.appcache"> <h1>YAY!</h1>
</html>
- checking
- noupdate
- downloading
- progress
- cached
- updateready
- obsolete
- error
... but it not the panacea
Unfortunately has it downsides
But hey! Let's try to fix it
or evolve it
AppCache and Firefox OS
If you are using appcache and have a Firefox OS app,
define it into the application manifest
{ "name": "My App", "description": "My elevator pitch goes here", "launch_path": "/",
"appcache_path": "manifest.appcache",
"icons": { "128": "/img/icon-128.png" }, "developer": { "name": "Your name or organization", "url": "http://your-homepage-here.org" }, "default_locale": "en" }
... and improve user experience
Web Apps with AppCache will download content before use
Firefox OS Packaged Apps
Another way of solving the offline problem is just downloading the whole content!
Packaged, on a simple format that we all know like ZIP
Firefox OS Packaged Apps
Simply add the following extra field to your application manifest
{ "name": "My App", "description": "My elevator pitch goes here", "launch_path": "/",
"package_path": "/application.zip",
"size": 1000000,
"icons": { "128": "/img/icon-128.png" }, "developer": { "name": "Your name or organization", "url": "http://your-homepage-here.org" }, "default_locale": "en" }
Extra information for Packaged Apps
Questions?
@mepartoconmigo
Thanks a lot!!
Don't miss the chance to know more about Firefox OS!
Ask us!
Working Offline
By Francisco Jordano
Working Offline
- 6,410