Working Offline with HTML5 web apps

with tips and trips for Firefox OS

Hi! I'm Francisco Jordano


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:




Are we online yet?

Losing connection happens more often than we expect

Are we online yet?

Check it!

if (navigator.onLine) { alert('online'); } else { alert('offline'); }
Supported in almost all the browsers.

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?


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

  • Can be modified server side
  • We send them with each request

The new kid on the block


  • 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;
... but ...

  • Cannot be accessed by workers
  • Funny implementation:
  • 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 ="MyBookShop", 1);

request.onsuccess = function onSuccess(event) {
    myDB =;
};request.onerror = function onError(event) {    alert('Sorry, cannot open the DB');};

IndexedDB example

We do have versioning! \o/

// Once opened the connectionrequest.onupgradeneeded = function onUpgradedNeeded(event) {
    var db =;
    var oldVersion = event.oldVersion;
    // Apply any schema upgrade if needed

We can modify the schema just within onupgradeneeded

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 =;
    if (!cursor) {/* We finished */}
    // Process each object in cursor.value

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.

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

# version 1.0


# Use from network if available

# Fallback content
/ offline.html
Server this file with mime type: text/cache-manifest

HTML5 AppCache

Use it in your html

<html manifest="manifest.appcache">

And/or listen to events:
  • 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": ""
  "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": "/",   "size": 1000000,  "icons": {
    "128": "/img/icon-128.png"
  "developer": {
    "name": "Your name or organization",
    "url": ""
  "default_locale": "en"

Extra information for Packaged Apps



Thanks a lot!!

Don't miss the chance to know more about Firefox OS!

Ask us!

Working Offline

By Francisco Jordano

Loading comments...

More from Francisco Jordano