Note: this presentation was written for Gistdeck. Add the bookmarklet, come back to this gist, click the bookmarklet, then use the arrow keys to navigate.
Note2: See https://github.com/meagar/taking-javascript-offline for code examples; any time a string like 2-basic-caching
appears, that's a branch which supports that slide
Matthew Eagar / Tech Lead / 500px
- Survey consumers on the street
- Take photos, capture signatures
- On Windows, IOS, Android devices
- Sync to central data store (Rails)
- With no wifi or cell network
- Appcache
- IndexedDB
- Location
- WebSockets
- FileReader
Store site structure in appcache
RESTful API for data
Temporary storage in IndexedDB
It worked!
- Sample Backbone app
- Basic RESTful API
- JS + Coffee + EJS + Jade?
1-no-cache
A mechanism for storing/accessing static assets offline
-
Driven by manifests
-
Define paths to cache
- JS/CSS/images/HTML
-
Full of gotchas
-
5mb limit
A douche bag :(
manifests...
- Contain sections, paths, comments
- included via
<html manifest="...">
- Served with Content-type: text/appcache *
- Have a .appcache extension *
- start with CACHE MANIFEST
CACHE MANIFEST
CACHE:
# Static assets
/js/jquery.js
/js/app.js
/css/bootstrap.css
/css/styles.css
# Single-page backbone apps
/posts
/users
<!doctype html>
<html manifest="/my_cache.appcache">
<head>
<script src="/js/jquery.js"></script>
<!-- ... -->
Add a basic manifest
Hooray for Chrome!
2-basic-caching
Once appcache'd, content only comes from appcache
On cached pages, all requests go through Appcache
On cached pages, all requests go through Appcache
Appcache only updates if the manifest changes
Request that triggers an update still comes from appcache
Changes require two page reloads to become apparent
On cached pages, all requests go through Appcache
On cached pages, all requests go through Appcache
Appcache allows NETWORK sections to define content that shouldn't be cached
CACHE MANIFEST
CACHE:
# Single-page backbone apps
/posts
/users
NETWORK:
/api/posts
2-basic-cache
You can't NETWORK a page which has a manifest; it's cached implicitly
Some content can't/shouldn't be cached
FALLBACK lets us provide defaults for use while offline
FALLBACK:
# Don't show user profiles while offline
/users/* /offline
Our SPA can detect the presence of a network connection and render accordingly
navigator.onLine // true/false
window.addEventListener('online', fn);
window.addEventListener('offline', fn);
3-going-offline
The appcache doesn't like slow networks
4-waiting-on-appcache
Manifest downloads are brittle
- Entire manifest is redownloaded
- Upgrade is interruptable
- Users unaware that updates are happening
- Errors cancel entire update
Appache emits several useful events
Can tie into them to provide a GUI for updates
First load:
- checking
- downloading
- progress(, progress, ...)
- cached
Subsequent loads
- checking
- noupdate
- downloading
- progress(, progress, ...)
- cached
More code!
- Detect cache downloading
- Show progress
4-waiting-on-appcache
Allows programatic expiration of the entire cache
Still subject to the double-reload requirement
Forces browser into uncached state
5-obsoletion
Obsolete caches!
Why obsoletion instead of updating?
-
/login - online only, set is_authorized
-
/index - offline
- check is_authorized
- bounce to index
- check is_authorized
-
/login - change to auth_token
Static sites for mobile!
Web apps that server structure first, data later
Anything!
Very quickly...
- A key/value store
- larger than localStorage
- Size varies from browser-to-browser
- Prompts the user for more storage
Very quickly...
- Doesn't warn you when it's full *
- Supports transactions, migrations, indices
- Faster than you might expect, slower than you might hope
Behavies like REST:
Backbone.sync
backbone-indexeddb.js
6-indexeddb