Application Cache or Service Workers - which to use in 2016/Q2?

北城余情 提交于 2019-11-30 00:01:48

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

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 :)

You're right, appcache is becoming unsupported.

And there are other options that store data and/or assets inside IDB such as:

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.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!