Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service Worker Caching doesn't work stable in Safari Desktop [webpack-plugin] #2540

Closed
Viktor286hearts opened this issue Jun 11, 2020 · 6 comments
Labels
Needs More Info Waiting on additional information from the community. workbox-precaching

Comments

@Viktor286hearts
Copy link

Viktor286hearts commented Jun 11, 2020

Library Affected:
workbox-webpack-plugin

Browser & Platform:
Safari Desktop 13.1.1

Issue or Feature Request Description:
Service Worker Caching doesn't work stable in Safari Desktop

Video demo of the issue

This is example of the issue with one chunk homepage.d5e2937.js available via SW cache in Chrome and not available in Safari after first pageload.
https://share.getcloudapp.com/7KumxYbd
image

This example of the issue with all chunks, Safari doesn't use SW cache after first load while Chrome does:
https://share.getcloudapp.com/8Lu7Zv8Q
image

Public URLs at which the issue could be reproduced: https://www.roadandtrack.com/

Steps to Reproduce:

Use Safari desktop, turn on "network" tab developer utilities (to monitor cache source for loaded assets)
Open https://www.roadandtrack.com/ on both Chrome(or Firefox) and Safari
Empty cache, clear site data and reload https://www.roadandtrack.com/

On each pageload take a look at the source of cache for js files "with-hash-in-title" (webpack bundle chunks) during pageload.
Observe initial pageload (js chunks served from remote server)
Observe second pageload (js chunks served from SW cache)
Observe pageload after more refreshes of the page (js chunks served from browser cache, not from SW cache)

Expected Result:

On initial page load – all files that suppose to be cached via SW loading as usual from remote server (first load prepare cache)
After very first (non hard) page refresh – all "hashed" files serves quickly from SW Cache
After EVERY other (non hard) page refresh – all "hashed" files serves quickly from SW Cache

Actual Result for Safari Desktop:

After EVERY other (non hard) page refresh – all "hashed" files serve through browser cache, SW not working.

Fix attempts:

Upgrade Workbox to v5 -- didn't make any effect on the issue.
Different workbox configurations -- didn't make any effect on the issue.

Findings:

Based on workbox logs, http requests weren't passed into service-worker by Safari and served from a native cache instead.
The issue could be related to not full support of "MessagePort API" in Service Workers by Safari

Related issues found:

[iOS] Safari is using memory cache instead of service worker

Background sync fallback in Safari not working

iOS Safari keeps refreshing on the log in page if SW is active.

Additional bugs which could be related:

We also can see on Safari Desktop that indexedDB overpopulated with timestamps records for cached files (probably for expiration "maxAgeSeconds" plugin)
indexedDB looks like another posted issue: Background Sync - post requests with images are not stored in IndexedDB queue on Mobile Safari (iOS 13.3.1)

Webpack Config:

new GenerateSW({
  swDest: 'sw.js',
  importsDirectory: `${outputPath}/js/shared`,
  precacheManifestFilename: 'precache-manifest.[manifestHash].js',
  importWorkboxFrom: 'local',
  skipWaiting: true,
  mode: 'production',
  inlineWorkboxRuntime: true,
  clientsClaim: true,
  sourcemap: false,
  runtimeCaching: [
    {
      handler: 'StaleWhileRevalidate',
      urlPattern: /^https:\/\/glimmer.*\/player\.js$/,
      options: {
        cacheName: 'glimmer-entry',
        fetchOptions: { mode: 'cors', credentials: 'omit' },
      },
    },
    {
      handler: 'CacheFirst',
      urlPattern: /^https:\/\/glimmer.*\/static\/.*\.js$/,
      options: {
        cacheName: 'glimmer-static',
        fetchOptions: { mode: 'cors', credentials: 'omit' },
        expiration: {
          maxEntries: 16, // at the moment of publication we have 4 static files for Glimmer
        },
      },
    },
  ],
})
@jeffposnick
Copy link
Contributor

Empty cache, clear site data and reload https://www.roadandtrack.com/

What you're describing—where you manually clear caches—sounds like you're deliberately entering into a situation in which the service worker's precached entries are deleted. workbox-precaching will automatically fall back to the network when there's a cached miss for a URL that should be precached, though that network response won't be used to repopulate the cache, because there's no guarantee that it corresponds to the version of the asset reflected in the cache manifest.

The next time there's a service worker update detected, the install event will fire again, and workbox-precaching will fully populate the precache, including any missing entries. But before that happens, what you're describing sounds pretty much like what I'd expect the behavior to be following someone clearing their caches.

@jeffposnick jeffposnick added Needs More Info Waiting on additional information from the community. workbox-precaching labels Jun 11, 2020
@Viktor286hearts
Copy link
Author

Viktor286hearts commented Jun 11, 2020

Hi @jeffposnick , thank you for quick reply! I am sure, that makes sense.

I am wondering if that is expected why this behavior presents only on Safari and not on other browsers?

Nevertheless, most of the time Safari doesn't use SW cache to serve files, at least from my current experience.

@Viktor286hearts
Copy link
Author

Viktor286hearts commented Jun 11, 2020

Shortly i will share a video to demonstrate the way this issue work on my side... having some internet issues

@Viktor286hearts
Copy link
Author

This is example of the issue with one chunk homepage.d5e2937.js available via SW cache in Chrome and not available in Safari after first pageload.
https://share.getcloudapp.com/7KumxYbd
image

This example of the issue with all chunks, Safari doesn't use SW cache after first load while Chrome does:
https://share.getcloudapp.com/8Lu7Zv8Q
image

@Viktor286hearts
Copy link
Author

@jeffposnick Please, let me know in case you need more info about this issue. Thanks!

@jeffposnick
Copy link
Contributor

There are some details at w3c/ServiceWorker#1174

Different browsers behave differently with regard to the memory cache for images and also for other subresources.

For images, the memory cache is checked before the service worker, and if there's a memory cache hit, a fetch event is never fired. (Without a fetch event, Workbox can't response to the request.)

For other subresources, the behavior is not specified anywhere, and different browsers might do different things. There isn't a single "correct" behavior.

Hopefully that, along with the explanation about what happens when you clear caches, explains what you're seeing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs More Info Waiting on additional information from the community. workbox-precaching
Projects
None yet
Development

No branches or pull requests

2 participants