navigator.onLine considered harmful

After several abortive attempts of trying to use HTML5 Application cache, I decided to turn Greptweet into an offline capable Web application and I learnt a ton along the way.

If you have code in your application that looks like:

if (navigator.onLine) {
	// Do something server side
} else {
	// Do something locally

You are probably doing it wrong. Why?

The navigator.onLine attribute is inherently unreliable. "A computer can be connected to a network without having Internet access." as says and as my suckless compatriots point out: Aside from physical link state, there is no way to tell the difference between an 'offline' network and a highly latent one. Again physical link state doesn't help you if your cable connected to your router is offline or you use wireless. Microsoft determines Internet connectivity by pinging one of their servers(!).

It gets worse if you are a luser because if you are sane and shun bloatware like dbus and the bonkers Network Manager then navigator.onLine will simply not report false on a typical Linux distribution like Debian or Archlinux when offline. Linux Chrome's navigator.onLine implementation for example depends on org.freedesktop.NetworkManager to work.

Whilst developing under Archlinux, Firefox's "Work offline" feature was a god send. Though Chrome's developer tools is much better to examine the Application Cache under the Resources section.

So what's the alternative to using navigator.onLine? I think individual Web apps need to determine navigator.onLine themselves by doing a http request to their Web site and if you don't get a 200 in x seconds you set your own navigator.onLine variable to false. I know at least one Web signage application that does this already. It's obviously important for a public sign to stay robust and work offline in the case of spotty internet connectivity.

After writing Greptweet with Offline HTML Appcache features, I don't think I need grep.php anymore. So another approach is to rely on sync using the cache manifest and localStorage, and design your Web application not to act on application data remotely.

Update via Twitter of course:

@kaihendry I've experimented with offline-first approach - always read from offline and sync in a worker thread emitting events @annevk

— Michael Mahemoff (@mahemoff) July 16, 2012

@kaihendry Cool. Chrome actually refused to add for a long time on the basis it's better to check yourself.

— Michael Mahemoff (@mahemoff) July 16, 2012

If you like this, you might like the stateless Web kiosk software I develop. Webconverger typically replaces Windows on PCs and is deployed in public and business environments for ease of deployment and privacy. Once installed it auto-updates making it painless to maintain. Try it where you exclusively use the only viable open platform... the Web!