Skip to content

scalarhq/service-worker-media-bug

Repository files navigation

Service Worker Media Storage Bug

We have a bug with caching and retrieving media from a service worker

The goal is to be able to intercept a request made from the video tag and serve it from a cache.

We are having problems with this for larger files of about 100mb+

We have looked at GoogleChrome/workbox#1663 (comment) and GoogleChrome/workbox#2382

But are experiencing a bug where the media is buffering for a long time with the service worker, especially during scrubbing and wanted to combat this.

You can experience this yourself at https://service-worker-testing.vercel.app/

This also seems like a bug specifically only on Chrome and not in firefox, it works as expected in firefox

Screenshots

These requests are taking forever to load when scrubbing, especially while moving back and fourth

image image

Code

The code for our service worker is in service-worker.setup.js

/* eslint-disable no-restricted-globals */
const { RangeRequestsPlugin } = require('workbox-range-requests')
const { registerRoute } = require('workbox-routing')
const { clientsClaim, skipWaiting } = require('workbox-core')
const { CacheFirst } = require('workbox-strategies/CacheFirst')
const {
  CacheableResponsePlugin
} = require('workbox-cacheable-response/CacheableResponsePlugin')

const { precacheAndRoute } = require('workbox-precaching/precacheAndRoute')

skipWaiting()
clientsClaim()

registerRoute(
  // Match /api/asset/<anything except getSignedUploadURL>
  ({ url }) => url.toString().match(/\/api\/asset\/(?!getSignedUploadURL).*/),
  new CacheFirst({
    cacheName: 'modfy-assets',
    matchOptions: {
      // TODO: I don't know what this does, research it
      ignoreVary: true,
      ignoreSearch: true
    },
    plugins: [
      // Only cache responses with status code 200 that have data from the signed
      // URL fetched
      new CacheableResponsePlugin({
        statuses: [200]
      }),
      new RangeRequestsPlugin()
    ]
  })
)

// eslint-disable-next-line no-restricted-globals
precacheAndRoute(self.__WB_MANIFEST || [])

self.onmessage = (event) => {
  if (event.data === 'claimMe') {
    self.clients.claim()
  } else if (event.data === 'isMultiplayer=true') {
    self.isMultiplayer = true
  } else if (event.data === 'isMultiplayer=false') {
    self.isMultiplayer = false
  }
}