Post on 08-May-2015
description
transcript
Offline Mode
WebApplicationsforOfflineUse
@pleckey|http://pleckey.me
Who is this guy?
PatrickLeckeyDirectorofEngineering
In-TouchInsightSystemsInc.
http://www.intouchinsight.com
Online is easy
Offline is ... easy?
But what if ...
... you're not guaranteed tohave connectivity the whole
way ...
What we have now ...
LocalStoragewindow.localStorage
ApplicationCachewindow.applicationCache
Chrome:4+,Firefox:3.5+,Safari:4+
MobileSafari:3.2+,AndroidBrowser:2.1+
IE:10+
LocalStoragesimple
straightforwardratherlimited
ApplicationCachecomplexconfusingpowerful
LocalStorage...it'sbasicallyashelf...
Putstuffontheshelf
Takestuffofftheshelf
Canonlyholdsomuchstuff
LocalStorage
SimilartoCookies...butnottransmittedoneachrequest
Sendwhatyouwant,whenyouwant!
LocalStorage
Key/ValuepairsLimitedstoragesize
SameOriginPolicy!http://pleckey.me!=https://www.pleckey.me
LocalStorage
5MBlimitAsJavaScriptstrings...
1.23456784bytefloat?9bytesofcharacters?
Nope!18-byteUTF-16string
LocalStorage
window.localStorage.getItem('foo');//null
window.localStorage.setItem('foo','bar');
window.localStorage.getItem('foo');//"bar"
window.localStorage.length;//1
JSON.stringify(window.localStorage);//{"foo":"bar"}
window.localStorage.removeItem('foo');//doesnothingifkeydoesn'texist
window.localStorage.clear();//removeALLitems
LocalStorage
What happens when the shelf is full?
try{window.localStorage.setItem('foo',really_big_thing);}catch(e/*DOMException*/){if(e.name=='QuotaExceededError')//Chrome,Safari,IEelseif(e.name=='NS_ERROR_DOM_QUOTA_REACHED')//Firefox}
LocalStorage
GoodIdeasapplicationstateuserinformation
BadIdeasbase64-encodedimages
postalcodelookupdatabase
ApplicationCache...isbasicallya...uh...cache...
Pre-cacheresources
Accessresourcesoffline
Fallbacktoalternatesfordynamicresources
ApplicationCache
NostoragelimitEvent-drivenAPI
CacheisbasedonmanifestURL
ApplicationCache
<htmlmanifest="/cache.manifest">
mimetypemustbetext/cache-manifest
cache.manifest
CACHE
NETWORK
FALLBACK
cache.manifestCACHE
CACHEMANIFEST#Version:8cf54be2
CACHE:/favicon.png/logo.png/site/page2.html
explicitlycachedresources
cache.manifestNETWORK
CACHEMANIFEST#Version:8cf54be2
CACHE:/favicon.png...
NETWORK:*
resourcesthatrequiretheusertobeonlineusuallyjust"*"
cache.manifestFALLBACK
CACHEMANIFEST#Version:8cf54be2
CACHE:/favicon.png/static.html
NETWORK:*
FALLBACK:/dynamic.php/static.html
resourcetoloadifrequestedresourcenotavailableoffline
ApplicationCache
cacheditemsarealwaysservedfromtheapplicationcache
theapplicationcachewillnotupdateunlessthecachemanifestfilecontentchanges
ApplicationCache
CACHEMANIFEST#Version:8cf54be2
CACHE:/script.js
NETWORK:*
textcontenthastobechanged
Pretty Simple, right?
...andyouthoughtit'dbethateasy...
Oops #1
Non-cachedresourcesdon'texist.
Evenwhenyou'reonline.
NETWORK:*
Oops #2
Theapplicationcacheworkswiththebrowsercache.
Sortof.
Cache-Control:max-age=9999999999
Oops #3
Cachingthecachemanifest.
It'llneverupdate.
Cache-Control:no-cache,no-store
Clearing the ApplicationCache
HTTP/1.0410Gone
ApplicationCache Events
window.applicationCache.addEventListener(...);/***'checking'-browserischeckingforanupdate(alwaysfirst)**'cached'-firedafterfirstdownloadofanewcachemanifest**'downloading'-new/updatedresourcesfound,browserisfetching**'error'-manifestreturned404oradownloadfailed**'noupdate'-cachemanifesthasnotchanged**'obsolete'-manifestreturned410,cachedeleted**'progress'-XofYmanifestresourcesdownloaded**'updateready'-allupdatesdownloaded*/
ApplicationCache API
window.applicationCache.addEventListener('updateready',function(e){alert('Newversiondownloaded.Applicationwillnowreload.');window.location.reload();});
window.applicationCache.update();
ApplicationCache API
window.applicationCache.addEventListener('updateready',function(e){alert('Newversiondownloaded.Applicationwillnowreload.');window.applicationCache.swapCache();});
window.applicationCache.update();
iframe is your friend
<!--iframe_js.html-->
<html><scripttype="application/javascript">
storelargelookupdatainiframes
iframe is your friend
<!--index.html-->
<htmlmanifest="/cache.manifest"><iframesrc="iframe_js.html"width="0"height="0"border="0"/></html>
CACHEMANIFEST#Version:1
CACHE:/iframe_js.html
NETWORK:*
includelookupdataincachemanifestloadviaiframe(sameorigin)
iframe is your friend
//index.htmlconsole
>window.awesome_data
Object{con:"foo",bar:"baz"}
varappCache=window.applicationCache;if(appCache.status!=appCache.status.CACHED){//notcachedyet,doanAJAXlookup}else{returnwindow.awesome_data.con;//"foo"}
Single Page Applications
pre-cachestaticresources(speed!)
Native(ish) Web App
<metaname="apple-mobile-web-app-capable"content="yes"/>
<metaname="mobile-web-app-capable"content="yes"/>
runsfullscreenbuilt-insoftwareupdates
queuedataforsubmissionlater
What Else Can I Do With This?
Comeworkforus!
SoftwareDeveloperUserExperienceDataScientist
Thank you!Questions?
@pleckey|http://pleckey.com