问题
Quick question for discussion really, as I wanted to have input from different people.
I am in the process of developing a web page app that must be available offline.
Now to do this, as I understand it, you would go about using either the application caching feature or by using service workers.
However, here is the conundrum I have. When researching the application cache, the MDN clearly states:
Deprecated:
This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.
After which another dialog box suggests using service workers instead.
The Service Workers page then goes on to state how Service Workers are an experimental technology, and it is best to consult the compatibility table.
The compatibility table says that Safari and Internet Explorer do not support Service Workers. Further consulting this site and assuming it is accurate, it states that work has begun by Microsoft to integrate service workers, however for Safari they are "Under consideration" with " Brief positive signals in five year plan."
Now this is a concern for the current project as it is essential that it be safari compatible, however, I also do not want it to break in other browsers.
What would be your recommendations? Simply go with the older Application Caching and update in the near future? Determine the users browser and act appropriately? Or, is there another way I am missing?
回答1:
You could choose to use Service Workers and AppCache on the same web app. What happens in such a case is that browsers that don’t support Service Workers will use AppCache, and those that do will ignore the AppCache and let the Service Worker take over.
Sources: https://www.w3.org/TR/service-workers/#activation-algorithm, https://crbug.com/410665
回答2:
There is definitely the option to use both at the same time. If you want to deploy a cross-browser application in the next couple of years, my impression is that you have to keep using AppCache, as iOS is only "thinking about" implementing Service Workers in the next 5 years.
Here's some JavaScript that we are using to detect whether to use one or the other and to initialize both
if ( 'serviceWorker' in navigator && b ) {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// Registration was successful
showMsg('ServiceWorker registration successful with scope: ', registration.scope);
if ( registration.installing ) {
showMsg( 'Service worker installing' );
} else if ( registration.waiting ) {
showMsg( 'Service worker installed' );
} else if ( registration.active ) {
showMsg( 'Service worker active' );
}
}).catch(function(err) {
// registration failed :(
showMsg('ServiceWorker registration failed: ', err);
});
// Listen for claiming our ServiceWorker
navigator.serviceWorker.addEventListener('controllerchange',
function(event) {
// Listen for changes in the state of our ServiceWorker
navigator.serviceWorker.controller.addEventListener('statechange', function() {
// If the ServiceWorker becomes "activated", let the user know they can go offline!
if (this.state === 'activated') {
// This example is refreshing the app directly, but you can inform the user with a fancy modal window or similar
window.location.reload( true );
}
});
});
// Browsers not using Service Workers
} else if ('applicationCache' in window) {
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = 'load-appcache.html'
document.body.appendChild(iframe);
showMsg("Iframe loaded for AppCache management");
} else {
showMsg("no service worker - no appCache");
}
The code described to initialize AppCache helps refreshing the new pages when the appcache file changes. I grabbed it from several sources but all coming from the powerful presentation that Patrick Kettner delivered during the PWA Dev Summit 2016: (https://www.youtube.com/watch?v=IgckqIjvR9U&t=1005s)
load-appcache.html contains nothing but
<!DOCTYPE html>
<html manifest="offline.appcache">
<head>
<title>loding appCache</title>
</head>
<body></body>
</html>
There are of course multiple possibilities that SW provides to deliver a fancier app, but with AppCache and IDB you can indeed do pretty much any business logic you want, including offline capabilities.
Beware that you will not be able to test AppCache functionality with Chrome as they have disabled it, but you can still force Firefox (I have tested with 50.1.0). You can always use Safari though :)
回答3:
You're right, appcache is becoming unsupported.
And there are other options that store data and/or assets inside IDB such as:
- Offline Web Applications with CouchDB, PouchDB and Emeber CLI
- Ember-Pouch
- Offline apps using Ionic Framework, PouchDB and AngularJS
Try googling "offline pouchdb ember" or "offline pouchdb angular" for more examples.
The only mechanisms for ensuring offline availability right now are service workers and appcache. Period.
All of these techniques rely on your site being a single page application and the entry point to be reachable. So if you are not using appcache or service workers to ensure the entry point is always reachable, you must fallback to http cache and properly set cache-related headers when serving your assets. Anyway, http cache can be evicted at any moment by the UA.
Facing this decision, if it is mandatory for the application to run offline and in Safari, the only option is to use appcache (AFAIK, there are no news about removing appcache from Safari).
To reduce the risk you could opt for combining one of the previous techniques (those that store assets on IndexedDB) in addition to appcache so the only thing you cache is the entry point for the SPA. If appcache becomes unsupported and there is no service worker alternative you could switch to the cache headers alternative.
Anyway, you can use feature detection (if ('serviceWorker' in navigator) { ... }
) to see if service workers are available and use it in case it is. There is a polyfill for appcache based on service workers called JakeCache (not tested) and others are to come.
回答4:
According to Mozilla's HTML5 Service Workers Doc:
Note: One great thing about service workers is that if you use feature detection like we’ve shown above, browsers that don’t support service workers can just use your app online in the normal expected fashion. Furthermore, if you use AppCache and SW on a page, browsers that don’t support SW but do support AppCache will use that, and browsers that support both will ignore the AppCache and let SW take over.
Code "above":
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-test/sw.js', {scope: '/sw-test/'})
.then(function(reg) {
// registration worked
console.log('Registration succeeded. Scope is ' + reg.scope);
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
}
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers
来源:https://stackoverflow.com/questions/36719454/application-cache-or-service-workers-which-to-use-in-2016-q2