Martin
Martin

Reputation: 43

Slow service-worker cache on IOS

I need help with my new project. I am trying to create web app what can run offline. For storing data I am using Firebase Firestore. In this moment I have this:

sw.js

self.addEventListener('install', function(e) {
  e.waitUntil(

     caches.open('airhorner').then(function(cache) {
        return cache.addAll([
          "/trasy.html",
          "/styles/all.css",
          "/styles/trasy.css",
          "/scripts/firebaseInit.js",
          "/scripts/trasy.js"
         ]);
       })

   );
});

self.addEventListener('fetch', function(event) {
  console.log(event.request.url);

  event.respondWith(
    caches.match(event.request).then(function(response) {
     return response || fetch(event.request);
    })
  );
});

Index.html:

  <!-- Some HTML with loading animation -->
  <script>
     if('serviceWorker' in navigator) {
        navigator.serviceWorker
          .register('/sw.js')
          .then(function() 
            { 
              window.location = "/trasy.html";                  
              console.log("Service Worker Registered"); 
            }
          );
     }
  </script>

Trasy.js:

  document.addEventListener("DOMContentLoaded", function(){
   db.collection("trasy").orderBy("list", "asc").get().then((snapshot) => {
    snapshot.forEach((doc) => {

       //Do some things with data from firestore

     });
   });
  })

And file Trasy.html (connected to Trasy.js for displaying data form DB).

I am trying to get data from Firestore. In my plan is that user go to Index.html, service-worker will be register, cache download, script will redirect user to trasy.html file, there Firestore get data from DB and display it.

It work... On Android, Windows and macOS perfectly. But on IOS browsers (chrome, safari, edge mobile etc...) when I was redirected to trasy.html loading data from Firestore take a long time (about 20 minutes).

I think the reason is that service-worker downloading files to cache and it block other scripts on trasy.html file. But why other OS are so fast and IOS is slow? What can I do?

Thanx.

Upvotes: 0

Views: 1058

Answers (1)

Priyashree Bhadra
Priyashree Bhadra

Reputation: 3607

To serve content from the cache and make your app available offline you need to intercept the network requests and respond with files stored in the cache. There are several approaches to this as per this documentation :

  • cache only
  • network only
  • cache falling back to network
  • network falling back to cache
  • cache then network

Actually, what you are doing is serving the content using cache falling back to the network strategy by using the code below :

event.respondWith( caches.match(event.request)
.then(function(response) { 
return response || fetch(event.request); 
})

which works like "Cache only" behavior for things in the cache and the "Network only" behaviour for anything not cached”, but rather what you want to use is either network falling back to the cache or cache then network strategy.

Network Falling back to Cache :

From the documentation,

Handling network requests this way means the online users get the most up-to-date content, and offline users get an older cached version. However, this method has flaws. If the user has an intermittent or slow connection they'll have to wait for the network to fail before they get content from the cache.

Unlike caches.match in your cache falling back to network strategy here we first send the request to the network using fetch(), and only if it fails do we look for a response in the cache.

Cache then network :

From the documentation,

This requires the page to make two requests: one to the cache, and one to the network. The idea is to show the cached data first, then update the page when/if the network data arrives.

Meaning : It will serve the content from cache immediately and then update the content as soon as the latest response is available via the n/w call. This is the most recommended strategy,

The problem in serving content from your current strategy is we are reading the cache content via e.respondWith(caches.match(e.request).then(function(response) but the update is happening via e.waitUntil(update(e.request)) in the next pass until the network call is completed which is not even used in this current read request.

So my suggestion is to increase the performance of the service workers by using the Cache then network strategy.

Upvotes: 1

Related Questions