device (naturally) • Almost always work offline • Direct access to device hardware • Shipped to end users via application stores • Built by mobile developers using specific programming languages and tools • Can be added to device’s Home Screen
downloaded and updated only via app stores • Not indexed by search engines • Cannot be shared via direct link • Difficult to reuse the code • Limited by the platform they are developed for • Excruciating process of getting app-roved : Low Maintenance : High
open URL • Are essentially web sites (with interaction capabilities) • Easily reusable code (HTML / CSS / Javascript) • Work across all platforms… but inside the browser • Indexed by search engines and easily discoverable • No approval needed to make your app available • They’re lightweight
like mobile apps • Poor access to native device hardware • They require Internet access and almost never work offline • Network performance affects user experience • Not safe (anyone can build and deploy a web app)
Will fit any device ✓ Works Offline Doesn’t depend on connectivity ✓ Native Look & Feel Native-like interaction and navigation ✓ Fresh Service Worker keeps the app up-to-date ✓ Safe Always served via HTTPS ✓ Discoverable Are indexed by Web Search Engines ✓ Engaging Engage enduser with features like Push Notifications ✓ Installable Can be added to device’s home screen ✓ Linkable Can easily be shared via URL and don’t need an app store
Will fit any device ✓ Works Offline Doesn’t depend on connectivity ✓ Native Look & Feel Native-like interaction and navigation ✓ Fresh Service Worker keeps the app up-to-date ✓ Safe Always served via HTTPS ✓ Discoverable Are indexed by Web Search Engines ✓ Engaging Engage enduser with features like Push Notifications ✓ Installable Can be added to device’s home screen ✓ Linkable Can easily be shared via URL and don’t need an app store
used in this version of the service worker. // Change to v2, etc. when you update any of the local resources, which will // in turn trigger the install event again. const PRECACHE = 'precache-v1'; const RUNTIME = 'runtime'; // A list of local resources we always want to be cached. const PRECACHE_URLS = [ 'index.html', ‘…’ ]; // The install handler takes care of precaching the resources we always need. self.addEventListener('install', event => { event.waitUntil( caches.open(PRECACHE) .then(cache => cache.addAll(PRECACHE_URLS)) .then(self.skipWaiting()) ); }); // The fetch handler serves responses for same-origin resources from a cache. // If no response is found, it populates the runtime cache with the response // from the network before returning it to the page. self.addEventListener('fetch', event => { // Skip cross-origin requests, like those for Google Analytics. if (event.request.url.startsWith(self.location.origin)) { event.respondWith( caches.match(event.request).then(cachedResponse => { if (cachedResponse) { return cachedResponse; } return caches.open(RUNTIME).then(cache => { return fetch(event.request).then(response => { // Put a copy of the response in the runtime cache. return cache.put(event.request, response.clone()).then(() => { is just a JavaScript file