I started playing with AppCache today after working at better offline support for LunchTable. Though information is well-dispersed on the topic (especially when it comes to using Google Fonts), I eventually sorted it.

Step 1. Add a cache manifest file

For more details, MDN is awesome.

My landing page contains <html manifest="manifest.appcache">, and manifest.appcache contains (abridged):

CACHE MANIFEST
# v1
NETWORK:
*

CACHE:
css/main.css
fonts/fontawesome-webfont.eot?v=4.0.3
fonts/fontawesome-webfont.eot?#iefix&v=4.0.3
fonts/fontawesome-webfont.woff?v=4.0.3
fonts/fontawesome-webfont.ttf?v=4.0.3
fonts/fontawesome-webfont.svg?v=4.0.3
js/myjs.js

The * under NETWORK: ensures that everything we don’t explicitly set here isn’t cached, because the next time we refresh it actually won’t load (see?).

Also note that we include query strings in the manifest; the CSS file references them this way, so we ensure they match here, because the browser cares.

Step 1.1. Serve the manifest file correctly

Your .appcache file should be served with the text/cache-manifest MIME type. On Apache, I added this to my universal server configuration:

AddType text/cache-manifest .appcache

Step 2. Host all previously remote files

Browsers also seem to care about caching files only from the application domain. I stopped using the FontAwesome CDN without a problem, but Google Fonts provided another hurdle.

Step 2.1. Host your Google Fonts

Based on some comments on this 2010 post, I found a simple script to download the font you want, and added a user agent for iPhone, though it doesn’t seem to do anything different right now (I was hoping to get SVGs), and needs testing.

family='Noto+Sans'; for url in $( { for agent in 'Mozilla/5.0 (X11; Linux i686; rv:6.0) Gecko/20100101 Firefox/6.0' 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1' 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)' 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_4 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B350 Safari/8536.25' ; do curl -A "$agent" -s "http://fonts.googleapis.com/css?family=$family" | grep -oiE 'http://[a-z0-9/._-]+'; done } | sort -u ) ; do extn=${url##*.} ; file=$(echo "$family"| tr +[:upper:] _[:lower:]); echo $url $file.$extn; curl -s "$url" -o "$file.$extn"; done

Simply replace Noto+Sans with the font you want, and add your newly downloaded fonts with something like this CSS in place of your old one-liner:

@font-face {
    font-family: 'Noto Sans';
    font-style: normal;
    font-weight: normal;
    src: url('/fonts/noto_sans.eot');
    src: url('/fonts/noto_sans.eot?#iefix') format('embedded-opentype'),
         url('/fonts/noto_sans.woff') format('woff'),
         url('/fonts/noto_sans.ttf') format('truetype');
}

Step 3. Test

To see what resources you’re caching on your site (as well as others), visit:

Chrome: chrome://appcache-internals
Firefox: about:cache?device=offline

Step 4. Read more

This is just the start, and there are a lot of additional concerns this kind of caching can add to your web application. But hopefully this will get you started. Besides LunchTable, forecast.io is another great app that uses this (look how fast it loads the second time!). $ logout

Advertisements