I'm looking into techniques for building a Progressive Web App in Aurelia with offline functionality that works across the major browsers. Service Workers are seemingly the preferred option for asset caching, but with lack of support in Safari (and currently Edge). Is it possible to use service workers with a fallback to appcache if they're not supported? How will an application behave if there's an appcache manifest AND a service worker installed?
if a browser supports service workers then the service worker caching will be used instead of the appCache manifest. You can include the appCache manifest for legacy browsers like Safari and things will work the way they did in the past. Plus for modern browsers they will leverage service worker caching and act as if the appCache does not exist. Sort of like the way responsive images work.
The check which technology the browser is supporting is easly done:
if(navigator.serviceWorker){
initServiceWorker()
}else if(window.applicationCache){
initApplicationCache();
}else{
console.log('no caching possible');
}
Dynamic loading a service worker should not be a problem since it is done in javascript anyway.
Dynamic loading applicationCache's mainfest seems not to be possible, but you can try an iframe hack, see: Dynamically Trigger HTML5 Cache Manifest file?
It's 2019 and iPhone still doesn't get the service worker functioning in WebViews. So a application cache fallback is still useful.
It's not exactly true that app cache will have no effect when service worker is up. It still tries to update its cache which is a silly thing to do. Turning it off isn't crucial but would be good thing to do.
The trick I'm doing now to disable app cache when service worker is functioning, is by intercepting the html (navigation) request and just remove the manifest
attribute from <html>
.
Something like this in the service worker script:
self.addEventListener('fetch', (ev) => {
if (request.mode === 'navigate' && request.method === 'GET') {
ev.respondWith(
fetch(ev.request.url)
.then(r => r.text())
.then(html => new Response(html.replace('manifest=', 'xmanifest='), {
headers: {'Content-Type': 'text/html'}
}))
)
}
})
© 2022 - 2024 — McMap. All rights reserved.