Don’t Wait for ServiceWorker: Adding Offline Support with One-Line

By  on  

The HTML5 Application Cache should make building offline-friendly web apps possible. In practice, its unforgiving nature makes it very challenging to use at all, giving it a uniquely negative reputation among front-end developers.

It's expected that apps continue to work offline—most users don't won't care about the implementation details, as long as their task isn't interrupted. This experience can be the same for apps built using web technologies, in a browser or a web view using PhoneGap/Cordova.

Offline-first applications have the added benefit of feeling faster, providing available information effectively even when a network connection isn't available.

It's not just apps that benefit from offline support: web-based slide frameworks need to run when the conference centre Wifi inevitably drops. Likewise, any travellers on spotty connections will appreciate (or, hopefully, not notice) when any articles or documentation they were expecting to have access to continue to work.

The future of offline-support

How do front-end developers actually go about building applications with offline support? The future appears to be ServiceWorker, but as Lyza Danger Gardner points out, ServiceWorker is only,

partially implemented in about 45 percent of the world's browsers—newer Chrome, Android, Opera browsers. That seems substantial; however, there is no official word that Safari will ever implement it.

Lyza Danger Gardner, How do we get it done, now?

Lyza points out three possible ways to overcome this technical challenge, all less than ideal:

  1. Only use ServiceWorker, meaning offline support will not work in most browsers, including on iOS
  2. Use the HTML5 Application Cache, and re-write offline support using ServiceWorker too
  3. Use only the HTML5 Application Cache

While the first option will work for some specific applications and audiences, most developers will need to choose one of the wider-reaching alternatives. Unfortunately, when a decision like this needs to be made, another option seems even more appealing:

  • Do nothing, and continue to ignore offline support.

It's sadly a reasonable conclusion, given those options. Often, web technologies are chosen precisely for their ability to deliver a cross-platform experience with a single codebase, yet two approaches are needed to deliver an wide-reaching, yet also forward-thinking, approach to offline support.

Falling back to the Application Cache requires generating an .appcache file and referencing it in the html attribute. Linking to it is easy; generating the file properly is complex.

ApathyCache

We think one way to improve offline support on the web is to make doing something—including basic offline support—easier by default. Offline support should be approachable, even if the HTML5 Application Cache is far from a flawless solution. With that in mind, we added an auto.appcache file to every project published on Surge, static web publishing for front-end developers.

Today, for every project on Surge, we automatically build an appropriate .appcache file, each time you publish your static site or client-side web app. To use it, you just have to opt-in by referencing it your html tag:

<html manifest="/auto.appcache">

This gives front-end developers the option of ignoring the challenging parts of using the AppCache manifest, instead buying them time to work on the satisfying parts: getting you app or static site to running offline, and working with newer technology like ServiceWorker.

Publishing to Surge

To install and publish a site on Surge, first install it through npm:

npm install --global surge

Next, run the command surge and pass in the directory of static files you'd like to publish to the web:

surge /path/to/my-project

This can be the compiled _site directory of a Jekyll project, the build directory of a React project, or a folder with an index.html file inside. Or, just run the command surge on its own, within the folder you want to publish.

Either way, you'll have the option of using a randomly generated subdomain, or specifying your own:

A gif showing the interface for the Surge command line tool, when you publish a project of flat files.

After this, your project will be published and live on the web. (You can also add a custom domain, if you'd like.)

Visit your auto.appcache file

This example was published to example-autoappcache.surge.sh. The auto.appcache will always be in the root of the project: example-autoappcache.surge.sh/auto.appcache.

The Automatic AppCache manifest file built on Surge is just an automatically formatted and maintained AppCache manifest file. It starts simply enough, with a simple declaration that is, in fact, a manifest file:

CACHE MANIFEST

From here, however, things begin to get more complex.

The cache section

In the first section, each static file in your project is automatically listed with two kinds of hashes. These hashes change when the contents of the file change—when you publish updated versions—but otherwise the application cache will continue to serve the old version.

CACHE:
/about.html
#  b6bdb311c874fa38b7e6e57a24f875ee  1233
/css/main.css
#  c7823b8fcc98bdf437ca00d7fefe3b3a  103
/index.html
#  1ef88ed5ba3b2645b6efad32530a4681  3009
/newsletter.html
#  4122172c8cfea3014425f322c82bc17a  980

This is normally one of the more complicated aspects of AppCache to deal with, and maintaining this file manually is completely impractical. There are some tools, like this Gulp plugin, that make maintaining this file locally much easier, but it is dependent on the toolchain you use to build your static site and client site app.

When you publish your site on Surge, we already do these checks to see if you have updated a file and we should propagate it across the Surge CDN, or if it remained unchanged since your last deploy. We're able to re-use that information as part of the manifest file to determine definitively if a more recent version of that resource is available or not.

The network section

Following the CACHE section is the network section. This combats a counter-intuitive part of how AppCache works: by default, only content in the cache section is available, online and offline. External resources are re-enabled with this section of the Auto AppCache manifest file:

NETWORK:
*

The fallback section

One part of Surge we're particularly proud of are the built-in clean URLs, and we found a way to maintain this behaviour through the FALLBACK section of the AppCache manifest file. This is also automatically generated for you in Surge's auto.appcache file, giving you clean URLs by default:

FALLBACK:
/about /about.html
/ /index.html
/newsletter /newsletter.html

Opting into offline support

While this file is generated for every project published to on Surge, developers still get to decide whether or not they'd like to opt-into using it.

To automatically cache your application or static site using the auto.appcache file, reference it in the manifest attribute in the <html> tag:

<html manifest="/auto.appcache">

By omitting the full URL, the file will 404 when you are developing your project locally, preventing any potentially confusing caching there.

Layering on ServiceWorker support

The automatically generated AppCache file won't work for every single project; as Jake Archibald points out, you can't put all of a site of Wikipedia's size into an .appcache file, for example. What the auto.appcache file does do, is make it significantly easier for people with web apps, blogs, documentation sites, or client-side applications getting wrapped up in Cordova, to easily opt-into basic offline support.

Hopefully, this buys developers the time they need to turn their focus to the more future-friendly and versatile technologies like ServiceWorker, secure in the knowledge that they have a fallback in place with much wider browser support.

Further reading

  • An example based on this article is available on GitHub
  • Gregor Martynus's AppCache Nanny adds further client-side automatic updates to offline first applications, and provides finder control of how the cache is used
  • Henrik Joreteg and Arthur Stolyar are both independently experimenting with generating AppCache manifest files as fallbacks for ServiceWorker
  • Jake Archibald's Offline Cookbook is a great resource on ServiceWorker
  • UpUp is a relatively new, but promising looking, wrapper around ServiceWorker
  • ServiceWorker requires a valid SSL certificate, which all projects published to surge.sh subdomains receive for free. Surge also support SSL for custom domains.
Kenneth Ormandy

About Kenneth Ormandy

Kenneth Ormandy is a designer at Surge. He organizes Vancouver's typography meetup, and contributes to the Lost Type Co-op.

Recent Features

  • By
    How I Stopped WordPress Comment Spam

    I love almost every part of being a tech blogger:  learning, preaching, bantering, researching.  The one part about blogging that I absolutely loathe:  dealing with SPAM comments.  For the past two years, my blog has registered 8,000+ SPAM comments per day.  PER DAY.  Bloating my database...

  • By
    How to Create a Twitter Card

    One of my favorite social APIs was the Open Graph API adopted by Facebook.  Adding just a few META tags to each page allowed links to my article to be styled and presented the way I wanted them to, giving me a bit of control...

Incredible Demos

  • By
    MooTools Wall Plugin

    One of the more impressive MooTools plugins to hit the Forge recently was The Wall by Marco Dell'Anna.  The Wall creates an endless grid of elements which can be grabbed and dragged, fading in elements as they are encountered.  Let me show...

  • By
    Truly Responsive Images with responsive-images.js

    Responsive web design is something you hear a lot about these days. The moment I really started to get into responsive design was a few months ago when I started to realise that 'responsive' is not just about scaling your websites to the size of your...

Discussion

  1. Landon

    Link to gulp plug-in is missing!

    https://github.com/hillmanov/gulp-manifest

  2. Tony

    If you use App Cache, then this is a must read I feel

    http://alistapart.com/article/application-cache-is-a-douchebag

  3. We should not be encouraging people to use appcache. We are trying to get it removed from the web platform. At this point, we should consider appcache deprecated.

  4. Lars

    So now it’s 2016, lots of things are happening..

    – AppCache API is deprecated
    – Microsoft Edge is implementing Service Worker
    – Webkit has SW “under consideration”
    – Firefox has full support
    – Chrome has full support (and with Chrome 50 also push data support)

    Stop using AppCache!

    • Charles

      March 25 2017: I’ll probably need AppCache for an upcoming project since we need to support iPhone users. :(

  5. Ed

    Seems like previous commenters may have missed the point of the article.

    Indeed, it is 2016. As of now, Webkit has not implemented SW and still may not.

    Therefore AppCache is (unfortunately) necessary if you want to build an offline web app today. And there is the ‘Surge’ service to take away some of the pain of appcache, right? So that you can focus on SW goodness.

    Or did I miss something?

  6. I am working with appcache and I am good with it. I wrote some code around it and with proper http headers set by server it works fine. Also, its transparent to my App code so I can switch to Workers once it will be reliable. Where I have problems id Android Webview (Chrome up to v22) on old devices such as S3. It seems it must be enabled programatically from java/c code but impossible from web. But hopefully everybody is using Chrome or Opera these days on such devices, BTW, Edge also supports AppCache. I have had problems only with firefox and its caching mechanisms which is hard to convince to don’t cahce or cache properly. Painfull..
    Also, when you use it in Chrome the console says: Switch to HTTPS, its deprecated for HTTP so, it will stay with us for a while ;)

  7. Nazim Jamil-Mir

    I believe the biggest concern over AppCache is the fact that it works over http, so will leave your application open to a man in the middle attack. This is simply not a risk worth taking, in my opinion.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!