The future of online is offline – Building modern web applications



The future of online is offline – Building modern web applications

0 0


talk-syncherts-july-2014

A talk at SyncHerts - July 2014

On Github matthew-andrews / talk-syncherts-july-2014

The future of online is offline

Building modern web applications

by Matt Andrews, FT Labs (mattandre.ws / @andrewsmatt)

Good hacks and great performance, smart multivariate responsiveness, and web apps that deserve far more than the lowly title of ‘page’.

FT App History

Summary

  • No review / approval process & automatic updates
  • Instant install
  • One app, many platforms
  • Direct relationship with readers
  • Apple don't take 30% cut
  • Native-ish: homescreen icon, swiping, offline, fast (enough)

The catch?

They're really difficult to make well :(

Offline challenges

  • Caching
  • Backwards compatibility
As a web developer it's really easy to forget how powerful the browser actually is - and how much work it does for you. Unlike traditional software development when you make a webpage you normally don't need to worry about memory management or garbage collection or backwards compatability - even if you do break something, most mistakes can be fixed by the user simply clicking refresh.

Caching for offline

Naive approach

  • if device is online, load from the web
  • else load from cache
  • Browser even has handy method for checking connection: navigator.onLine

What does online mean anyway?

At best, that the device is connected to a wired or wireless router

navigator.onLine doesn't work

Fun fact:

On Desktop Firefox navigator.onLineis only false when File » Work Offline is ticked

Who even uses that anyway?

So how do we know if we're online?

You don't need to know

Live with uncertainty

  • Always assume the device is offline, load from cache
  • Then try the network for new data in the background
(Also stops slow connections ruining your site)

For a page to load offline,you need to use the HTML5 Application Cache

Manifest looks like this:

CACHE MANIFEST
# 2014-05 v1
/lib/fonts/BentonSansBold.ttf
/lib/img/startupscreen/splash-logo.png

NETWORK
*

And to use it you need to add an attribute to <html>

<DOCTYPE html>
<html manifest="mywebapp.manifest">

Sadly, it's not quite that easy

  • Leaks storage (workarounds exist)
  • Inflexible and unintuitive API
  • Makes browser susceptible to scary man in the middle attacks… whether you use it or not
  • Will soon be replaced by Service Worker
Technically already available in Canary, behind a flag - but you can only install, uninstall and send messages to it right now - all the cool offline stuff not ready yet
Even Chrome dev relations people will tell you the Application Cache is a douchebag.

But…

  • It does work
  • across 80%+* of browsers (iOS, Android, Chrome, Opera, IE10+)
  • Only Chrome and Firefox have committed to building Service Worker implementations

* http://caniuse.com/offline-apps

AppCache OK

  • Yes it's ugly for developers
  • But it enables amazing experiences for users
  • There are use cases where it works well
  • Unfortunately, building a newspaper app isn't one of them

Service Workers

The spec says:

Service Workers are a new browser feature that provide event-driven scripts that run independently of web pages […] They have access to domain-wide events such as network fetches. ServiceWorkers also have scriptable caches. Along with the ability to respond to network requests from certain web pages via script, this provides a way for applications to "go offline". https://github.com/slightlyoff/ServiceWorker/

A Service Worker:

  • is a javascript file that you write and can be 'installed' onto your website
  • lets you to do things with requests between browser and server
  • has special caches that you can reliably store content in

More code than AppCache - but you can read what it does!

// Install process
this.oninstalled = function(event) {
  var myCache = new Cache(
    '/lib/fonts/BentonSansBold.ttf',
    '/lib/img/startupscreen/splash-logo.png'
  );

  // The coast is only clear when all the resources are ready.
  event.waitUntil(myCache.ready());

  // Add Cache to the global so it can be used later during onfetch
  caches.set("my-cache", myCache);
};

// (scroll for more)

// Request handling
this.addEventListener("fetch", function(e) {
  e.respondWith(caches.match(e.request));
});

Backwards compatibility

Unlike native apps,offline websites only download updates

when they're open

and only apply those updates on refresh

And some users get stuck on old versions - we're still detecting API callsfrom Javascript that hasn't been served for a year

App start events split by version of client side code

Guidance

  • Expect some users to get stuck, add tools to help users recover their apps
  • Test different versions of client side code against different backend versions
  • Add monitoring
  • Add buttons to recovery tools that appear after a CSS animation if JS fails
  • Version everything - API endpoints, data formats
  • Client side database migrations are painful. Store data in its simplest form (JSON better than HTML)

Summary

  • Offline websites are possible today, with enough persistence
  • … but expect some users to get stuck
  • Service Worker will make things better (but only on Chrome & Firefox)
  • Test, measure and monitor everything

Questions?

@andrewsmatt

Offline Web Workshop

I'm running a workshop at SmashingConf onthe Offline Web in September in Freiberg