3

I was following an Internet tutorial about progressive web apps, with the following examples (MWEs of the important files):

service-worker.js:

var dataCacheName = 'template-pwa';
var cacheName = 'template-pwa';
var filesToCache = [
  './',
 "./fonts",
 "./fonts/roboto",
 "./fonts/roboto/Roboto-Bold.woff",
 "./fonts/roboto/Roboto-Bold.woff2",
 "./images",
 "./images/icons",
 "./images/icons/icon-128x128.png",
 "./index.html",
 "./manifest.json",
 "./scripts",
 "./scripts/app.js",
 "./scripts/jquery-3.3.1.js",
 "./scripts/materialize.js",
 "./service-worker.js",
 "./styles",
 "./styles/materialize.css",
 "./styles/style.css"
];

self.addEventListener('install', function(e) {
  console.log('[ServiceWorker] Install');
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      console.log('[ServiceWorker] Caching app shell');
      return cache.addAll(filesToCache);
    }).catch(reason => console.error(reason))
  );
});

self.addEventListener('activate', function(e) {
  console.log('[ServiceWorker] Activate');
  e.waitUntil(
    caches.keys().then(function(keyList) {
      return Promise.all(keyList.map(function(key) {
        if (key !== cacheName && key !== dataCacheName) {
          console.log('[ServiceWorker] Removing old cache', key);
          return caches.delete(key);
        }
      }));
    })
  );
  return self.clients.claim();
});

self.addEventListener('fetch', function(e) {
  console.log('[Service Worker] Fetch', e.request.url);
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || fetch(e.request);
    })
  );
});

manifest.json:

{
  "name": "Template PWA",
  "short_name": "Template PWA",
  "icons": [{
    "src": "images/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    }, 
    }],
  "start_url": "./index.html",
  "display": "standalone",
  "background_color": "#3E4EB8",
  "theme_color": "#2F3BA2"
}

app.js:

(function() {
  'use strict';

  window.onload = function() {
    let message = localStorage.getItem("message") || 'Your message will display here';
    $('#message').html(message);
    $('#display').html(message);
  }

  $('#button').click(() => {
    console.log('click')
    let message = $('#message').val();
    console.log(message);
    $('#display').html(message);
    localStorage.setItem("message", message);
  });

  if ('serviceWorker' in navigator) {
    navigator.serviceWorker
             .register('./service-worker.js')
             .then(function() { console.log('Service Worker Registered'); });
  }
})();

When I run the PWA on my website, visit the PWA with my smartphone and add the PWA to my homescreen I can use it as expected. When I go offline (airplane mode), I can still use the PWA as expected. However, when I drag the screen down (refresh), the PWA displays "site cannot be reached".

Shouldn't a progressive web app be completely cached to be usable offline?

JJ Abrams
  • 365
  • 2
  • 11
  • 1
    If you think about it, the behavior makes sense. The user is explicitly asking for a refresh of the page. Since they are not online, it fails. Seems like a reasonable behavior to me. If you don't want that error message to occur, [prevent it from allowing pull-down-to-refresh](https://stackoverflow.com/q/29008194/215552). – Heretic Monkey Dec 16 '18 at 21:35
  • Apparently I completely misunderstood the idea behind PWAs. But as you said, if the user refreshes, it's obvious to fail, since the user wants an up to date version and not the cached. Thanks for the explanation :) – JJ Abrams Dec 16 '18 at 22:17
  • 1
    That's not the expected behavior. Your application should be able to gracefully manage refresh when there's is no connection. Either implicitly or explicitly. If your system shows an internet error is because there should be some request (api, image, etc.) that you are not handle properly. – Gi1ber7 Feb 14 '19 at 18:56

0 Answers0