Taking your “web” app to places you never expected - Ember Fest 2014
-
Upload
williamsgarth -
Category
Software
-
view
153 -
download
1
description
Transcript of Taking your “web” app to places you never expected - Ember Fest 2014
IAEA International Atomic Energy Agency
Taking Your “Web” App To places you never expected
Garth Williams @williamsgarth
IAEA
Background
• The IAEA inspects nuclear facilities all over the world
• The IAEA is currently modernising a number of legacy applications
• Our inspectors need to collect and store data where no network connection is guaranteed or even allowed
• Our team is writing the next version of software for facility inspections
IAEA
Let’s use WPF?
• A desktop app is the logical choice, right?
• Organisation standards are based on Microsoft technologies
• So Windows Presentation Foundation must be the right choice?
• (Oh, by the way, we may need to support tablets in 2015)
IAEA
Why HTML(5) is better
• HTML5 includes all the building blocks for offline apps
• Web apps don’t need to be installed
• HTML is portable
IAEA
Ember is a good fit
• Full stack framework
• Well suited to larger projects:
• Ember offers familiar conventions
• Ember encourages consistency and structure through the use of components, ember data, stateful routing, etc…
• Compiles down to one or two js distributables
IAEA
Taking ember offline (manifest.appcache)
• Use a manifest file • Lists all resources needed when offline
• CSS, Fonts, Images, JavaScript, HTML, etc… • Referenced in your html tag
<!DOCTYPE*html>*<html*manifest=“/manifest.appcache”>***…*</html>
IAEA
Taking ember offline (manifest.appcache)
CACHE*MANIFEST*#-Version-1.0.0-!
CACHE:*/js/app.js*/css/app.css*/images/logo.png*/fonts/fontawesomeJwebfont.woff*/404.html*!
NETWORK:*/api*!
FALLBACK:*/*/404.html
IAEA
What about my beautiful client side URLs?
• Single page apps used to use # for client side routing
• For an app is located at
• https://stunningapp.com/
• When the client navigates to entity 5 then we can have
• https://stunningapp.com/#/entity/5
IAEA
What about my beautiful client side URLs?
• But now I’m using push state, how can this dynamic url be available offline?
• https://stunningapp.com/entity/5/
IAEA
What about my beautiful client side URLs?
• Use the FALLBACK section of the manifest file
CACHE*MANIFEST*!
CACHE:*/*!
FALLBACK:*#-normal-fallback:-/-/404.html-#-Support-Push-State-/*/
• Any page not stored locally will return the cached root page
IAEA
Caching hell & double reloads
• First time a browser visits your app:
1. HTML is downloaded
2. Manifest is detected and downloaded
3. Resources listed in manifest are downloaded and stored
IAEA
Caching hell & double reloads
• On subsequent visits:
1. Cached version of all app files are used
• Fast load time!
• Potentially out of date!
2. Check if manifest file has changed
IAEA
Caching hell & double reloads
• Manifest is only checked on first load
• Long running apps won’t know there’s a new version
• Only the manifest file is checked
• Changes in other files will not be detected
• If there is a new version it will be silently downloaded
• User is not automatically informed
• Changes are not applied until reload
IAEA
Caching hell & double reloads
• Mitigation:
1. Auto-generate the manifest
• Put a content hash of cached files in a comment
CACHE*MANIFEST*!
CACHE:*#-app.js-hash:-1921ec2e922f7f11c73c870e908b1c50-/js/app.js
IAEA
Caching hell & double reloads
• Mitigation:
2. Notify the user
applicationCache.addEventListener('updateready',*function*()*{***//*let*the*user*know*that*they*need*to*reload*});
IAEA
Caching hell & double reloads
• During development you may spend a lot of time reloading the app
• 1 reload is not enough
• 1st reload will download the changes
• 2nd will put them into effect
• 2 reloads is tedious
• If you reload too quickly it might not work
IAEA
Caching hell & double reloads
• Mitigation:
3. Periodically check for a new version
setInterval(function*()*{***applicationCache.update();*},*config.newVersionCheckInterval);
• If the manifest has changed then it will be downloaded in the background
IAEA
Toggle online only features
• Some features require a server
• We can check network connection status
• Also need to check if the server can be reached
IAEA
Toggle online only features
• Detecting network availability
var*updateNetworkStatus*=*function*()*{***if*(applicationController.get('isNetworkConnected')*!==*navigator.onLine)*{*****applicationController.set('isNetworkConnected',*navigator.onLine);*****//*if*we*just*moved*from*offline*to*online*check*for*app*update*****if*(navigator.onLine)*{*******applicationCache.update();*****}***}*};*window.addEventListener('online',*updateNetworkStatus);*window.addEventListener('offline',*updateNetworkStatus);
IAEA
Toggle online only features
• Detecting service availability
var*updateServiceStatus*=*function*(status)*{***applicationController.set('isServiceAvailable',*status.type*!==*'error');*};*!
applicationCache.addEventListener('error',*updateServiceStatus);*applicationCache.addEventListener('noupdate',*updateServiceStatus);*applicationCache.addEventListener('updateready',*updateServiceStatus);
IAEA
Toggle online only features
• Putting network and service status together
isOnline:*function*()*{***return*this.get('isNetworkConnected')*&&*this.get('isServiceAvailable');*}.property('isNetworkConnected',*'isServiceAvailable')
IAEA
Data Access
• Ember data offers useful layered abstractions
• An adaptor lets you communicate with your data source
• A serialiser lets you transform from the format of your source to the format expected by ember
• The store provides an agnostic API for application to load and save models
IAEA
Data Access
• Server side we’re using ASP.NET MVC Web API
• Requires a custom Adaptor and Serialiser
• Adding offline support at the adaptor level is easy
• Application code does not need know
IAEA
Data Access
• Oversimplified data adaptor
var*CacheAdapter*=*DS.RESTAdapter.extend({***ajax:*function*(url,*type,*options)*{*****if*(App.get('isOnline'))*{*******options.success*=*function*(responseData)*{*********cacheResponse(url,*type,*options,*responseData);*******};*******return*this._super(url,*type,*options);*****}*else*{*******return*cachedResponse(url,*type,*options);*****}***}*});
IAEA
Data Access
• Not always desirable to cache every response
• Pass intentions to store methods
IAEA
Data Accessstore.findById('person',*id,*{*cacheResponse:*true*});
var*CacheStore*=*DS.Store.extend({***findById:*function*(type,*id,*options)*{*****return*this.findQuery(type,*{*id:*id*},*options).then(function*(result)*{*******return*result.get('firstObject');*****});***},*!
**findQuery:*function*(type,*data,*options)*{*****data*=*data*||*{};*****data.__options*=*options*||*{};*****return*this._super(type,*data);***}*});
IAEA
Hold on… “new” requirement
• We forgot to mention…
• Sometimes it’s not possible to bring the laptop/tablet back to headquarters
• How can you deploy and update a web app to a computer that never connects to the server?
IAEA
Hold on… “new” requirement
• At a small number of locations, the only hardware allowed back to HQ is a hardware encrypted USB stick…
• Put the browser on the USB stick
• Configure the browser to store all data cache data on the USB
• Now when at HQ the browser will update the app and store data needed ready for offline use
IAEA
Recap
• Ember offers the structure necessary for large (and small) projects
• Build tools like ember-cli give you manageable output for manifest.appcache and can easily be extended to automate its content
• Build automation is essential from the start when using appcache
• Ember data has the abstractions necessary to provide good offline support which can be transparent to your app
• There’s not much that you can’t do with Ember.js “web” application
IAEA
Questions?